diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index c061edd7a..696ee3277 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -8,6 +8,11 @@ === Breaking changes +- All services that were previously available in `org.eclipse.syson.sysml.helper` package of `syson-sysml-metamodel` module have been moved to `org.eclipse.syson.sysml.metamodel.helper` package of `syson-sysml-metamodel-services` module. +- All services that were previously available in `org.eclipse.syson.sysml.textual` package of `syson-sysml-metamodel` module have been moved to `org.eclipse.syson.sysml.metamodel.services.textual` package of `syson-sysml-metamodel-services` module. +- All services that were previously available in `org.eclipse.syson.sysml.textual.utils` package of `syson-sysml-metamodel` module have been moved to `org.eclipse.syson.sysml.metamodel.services.textual.utils` package of `syson-sysml-metamodel-services` module. +- All services that were previously available in `org.eclipse.syson.sysml.util` package of `syson-sysml-metamodel` module have been moved to `org.eclipse.syson.sysml.metamodel.util` package of `syson-sysml-metamodel-services` module. + === Dependency update - [releng] Update to https://github.com/vitejs/vite/releases/tag/v8.0.13[Vite 8.0.13] and https://github.com/vitejs/vite-plugin-react/releases/tag/plugin-react%406.0.2[`@vitejs/plugin-react` 6.0.2]. diff --git a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/configuration/SysMLv2RewriteProxiesResourcesFilter.java b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/configuration/SysMLv2RewriteProxiesResourcesFilter.java index ce44cdcfa..cda329cb2 100644 --- a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/configuration/SysMLv2RewriteProxiesResourcesFilter.java +++ b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/configuration/SysMLv2RewriteProxiesResourcesFilter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024, 2025 Obeo. + * Copyright (c) 2024, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -14,7 +14,7 @@ import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.sirius.web.application.project.services.api.IRewriteProxiesResourceFilter; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.springframework.stereotype.Service; /** diff --git a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/configuration/SysONDefaultLibrariesConfiguration.java b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/configuration/SysONDefaultLibrariesConfiguration.java index 70cf6bb93..bd296f626 100644 --- a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/configuration/SysONDefaultLibrariesConfiguration.java +++ b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/configuration/SysONDefaultLibrariesConfiguration.java @@ -28,8 +28,8 @@ import org.eclipse.syson.application.libraries.SysONLibraryLoader; import org.eclipse.syson.application.libraries.SysONLibraryLoadingDefinition; import org.eclipse.syson.sysml.SysmlPackage; -import org.eclipse.syson.sysml.helper.EMFUtils; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.helper.EMFUtils; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.eclipse.syson.sysml.util.LibraryNamespaceProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/index/SysONIndexUpdateService.java b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/index/SysONIndexUpdateService.java index cc7e4072c..d48e518f3 100644 --- a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/index/SysONIndexUpdateService.java +++ b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/index/SysONIndexUpdateService.java @@ -30,7 +30,7 @@ import org.eclipse.sirius.web.infrastructure.elasticsearch.services.api.IIndexCreationService; import org.eclipse.sirius.web.infrastructure.elasticsearch.services.api.IIndexDeletionService; import org.eclipse.sirius.web.infrastructure.elasticsearch.services.api.IIndexUpdateServiceDelegate; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; diff --git a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/migration/DiagramOnViewUsageMigrationHook.java b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/migration/DiagramOnViewUsageMigrationHook.java index 39a6a8729..fe17981f9 100644 --- a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/migration/DiagramOnViewUsageMigrationHook.java +++ b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/migration/DiagramOnViewUsageMigrationHook.java @@ -37,7 +37,7 @@ import org.eclipse.syson.sysml.SysmlFactory; import org.eclipse.syson.sysml.ViewDefinition; import org.eclipse.syson.sysml.ViewUsage; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.eclipse.syson.util.GetIntermediateContainerCreationSwitch; import org.eclipse.syson.util.StandardDiagramsConstants; import org.eclipse.syson.util.SysONRepresentationDescriptionIdentifiers; diff --git a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/migration/OneDiagramDescriptionMigrationHook.java b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/migration/OneDiagramDescriptionMigrationHook.java index 93f2303d6..684d0f39b 100644 --- a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/migration/OneDiagramDescriptionMigrationHook.java +++ b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/migration/OneDiagramDescriptionMigrationHook.java @@ -30,7 +30,7 @@ import org.eclipse.sirius.web.domain.boundedcontexts.representationdata.services.api.IRepresentationMetadataUpdateService; import org.eclipse.sirius.web.domain.boundedcontexts.semanticdata.SemanticData; import org.eclipse.syson.sysml.Element; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.eclipse.syson.util.SysONRepresentationDescriptionIdentifiers; import org.springframework.data.jdbc.core.mapping.AggregateReference; import org.springframework.stereotype.Service; diff --git a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/migration/StandardLibrariesElementsDiagramMigrationParticipant.java b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/migration/StandardLibrariesElementsDiagramMigrationParticipant.java index 335721665..0d8ed194c 100644 --- a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/migration/StandardLibrariesElementsDiagramMigrationParticipant.java +++ b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/migration/StandardLibrariesElementsDiagramMigrationParticipant.java @@ -18,7 +18,7 @@ import org.eclipse.sirius.components.core.api.IEditingContext; import org.eclipse.sirius.components.core.api.IObjectSearchService; import org.eclipse.syson.sysml.Element; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.springframework.stereotype.Service; import tools.jackson.databind.JsonNode; diff --git a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/migration/StandardLibrariesElementsReferencesMigrationParticipant.java b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/migration/StandardLibrariesElementsReferencesMigrationParticipant.java index ca12d5ce1..d657f06f9 100644 --- a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/migration/StandardLibrariesElementsReferencesMigrationParticipant.java +++ b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/migration/StandardLibrariesElementsReferencesMigrationParticipant.java @@ -21,7 +21,7 @@ import org.eclipse.sirius.components.emf.migration.api.IMigrationParticipant; import org.eclipse.sirius.emfjson.resource.JsonResource; import org.eclipse.syson.sysml.Element; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.springframework.stereotype.Service; /** diff --git a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/publication/SysONSysMLLibraryPublisher.java b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/publication/SysONSysMLLibraryPublisher.java index 7631e1cfa..d55a72d2a 100644 --- a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/publication/SysONSysMLLibraryPublisher.java +++ b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/publication/SysONSysMLLibraryPublisher.java @@ -51,7 +51,7 @@ import org.eclipse.syson.application.publication.api.ISysONLibraryDependencyCollector; import org.eclipse.syson.application.services.SysONResourceService; import org.eclipse.syson.services.api.ISysONResourceService; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.jdbc.core.mapping.AggregateReference; diff --git a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/search/SysONSearchService.java b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/search/SysONSearchService.java index 9b084a55c..e81570f91 100644 --- a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/search/SysONSearchService.java +++ b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/search/SysONSearchService.java @@ -30,7 +30,7 @@ import org.eclipse.sirius.web.application.library.services.LibraryMetadataAdapter; import org.eclipse.sirius.web.application.views.search.dto.SearchQuery; import org.eclipse.sirius.web.application.views.search.services.api.ISearchService; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Primary; diff --git a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/services/DetailsViewService.java b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/services/DetailsViewService.java index 3eb15621b..bd072b566 100644 --- a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/services/DetailsViewService.java +++ b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/services/DetailsViewService.java @@ -70,9 +70,9 @@ import org.eclipse.syson.sysml.Type; import org.eclipse.syson.sysml.ViewUsage; import org.eclipse.syson.sysml.metamodel.services.ElementInitializerSwitch; -import org.eclipse.syson.sysml.textual.SysMLElementSerializer; -import org.eclipse.syson.sysml.textual.SysMLSerializingOptions; -import org.eclipse.syson.sysml.textual.utils.FileNameDeresolver; +import org.eclipse.syson.sysml.metamodel.services.textual.SysMLElementSerializer; +import org.eclipse.syson.sysml.metamodel.services.textual.SysMLSerializingOptions; +import org.eclipse.syson.sysml.metamodel.services.textual.utils.FileNameDeresolver; /** * Java services needed to execute the AQL expressions used in the {@link SysMLv2PropertiesConfigurer}. diff --git a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/services/SysONIdentityService.java b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/services/SysONIdentityService.java index 5b4143d93..9674f8562 100644 --- a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/services/SysONIdentityService.java +++ b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/services/SysONIdentityService.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024, 2025 Obeo. + * Copyright (c) 2024, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -19,7 +19,7 @@ import org.eclipse.sirius.components.emf.services.IDAdapter; import org.eclipse.syson.sysml.Element; import org.eclipse.syson.sysml.Relationship; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.springframework.stereotype.Service; /** diff --git a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/services/SysONReadOnlyObjectPredicateDelegate.java b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/services/SysONReadOnlyObjectPredicateDelegate.java index e068c49dd..13e4766b8 100644 --- a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/services/SysONReadOnlyObjectPredicateDelegate.java +++ b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/services/SysONReadOnlyObjectPredicateDelegate.java @@ -19,7 +19,7 @@ import org.eclipse.sirius.components.core.api.IReadOnlyObjectPredicateDelegate; import org.eclipse.sirius.components.emf.ResourceMetadataAdapter; import org.eclipse.syson.sysml.Element; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.springframework.stereotype.Service; /** diff --git a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/services/SysONResourceService.java b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/services/SysONResourceService.java index eabbd7e1d..d839c3580 100644 --- a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/services/SysONResourceService.java +++ b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/services/SysONResourceService.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2025 Obeo. + * Copyright (c) 2025, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -25,7 +25,7 @@ import org.eclipse.sirius.web.domain.boundedcontexts.library.services.api.ILibrarySearchService; import org.eclipse.sirius.web.domain.boundedcontexts.semanticdata.SemanticData; import org.eclipse.syson.services.api.ISysONResourceService; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.springframework.data.jdbc.core.mapping.AggregateReference; import org.springframework.stereotype.Service; diff --git a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/sysmlv2/SysONDefaultResourceProvider.java b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/sysmlv2/SysONDefaultResourceProvider.java index 1567876be..26d40878c 100644 --- a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/sysmlv2/SysONDefaultResourceProvider.java +++ b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/sysmlv2/SysONDefaultResourceProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024, 2025 Obeo. + * Copyright (c) 2024, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -27,7 +27,7 @@ import org.eclipse.sirius.components.emf.services.JSONResourceFactory; import org.eclipse.syson.application.sysmlv2.api.IDefaultSysMLv2ResourceProvider; import org.eclipse.syson.sysml.SysmlFactory; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.ClassPathResource; diff --git a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/update/SysONEditingContextSnapshotService.java b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/update/SysONEditingContextSnapshotService.java index 72265c4eb..e39f324bb 100644 --- a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/update/SysONEditingContextSnapshotService.java +++ b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/update/SysONEditingContextSnapshotService.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2025 Obeo. + * Copyright (c) 2025, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -29,7 +29,7 @@ import org.eclipse.sirius.web.application.editingcontext.services.api.IResourceToDocumentService; import org.eclipse.sirius.web.application.library.services.LibraryMetadataAdapter; import org.eclipse.syson.application.configuration.SysMLEditingContextProcessor; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Service; diff --git a/backend/application/syson-application-configuration/src/test/java/org/eclipse/syson/application/services/DetailsViewServiceTest.java b/backend/application/syson-application-configuration/src/test/java/org/eclipse/syson/application/services/DetailsViewServiceTest.java index 0f48b5c95..b533be80e 100644 --- a/backend/application/syson-application-configuration/src/test/java/org/eclipse/syson/application/services/DetailsViewServiceTest.java +++ b/backend/application/syson-application-configuration/src/test/java/org/eclipse/syson/application/services/DetailsViewServiceTest.java @@ -30,7 +30,7 @@ import org.eclipse.syson.sysml.Package; import org.eclipse.syson.sysml.SysmlFactory; import org.eclipse.syson.sysml.SysmlPackage; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/backend/application/syson-application-configuration/src/test/java/org/eclipse/syson/application/services/SysONReadOnlyObjectPredicateDelegateTests.java b/backend/application/syson-application-configuration/src/test/java/org/eclipse/syson/application/services/SysONReadOnlyObjectPredicateDelegateTests.java index 7822b9758..b1cd500a9 100644 --- a/backend/application/syson-application-configuration/src/test/java/org/eclipse/syson/application/services/SysONReadOnlyObjectPredicateDelegateTests.java +++ b/backend/application/syson-application-configuration/src/test/java/org/eclipse/syson/application/services/SysONReadOnlyObjectPredicateDelegateTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2025 Obeo. + * Copyright (c) 2025, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -38,8 +38,8 @@ import org.eclipse.syson.sysml.OwningMembership; import org.eclipse.syson.sysml.Package; import org.eclipse.syson.sysml.SysmlFactory; -import org.eclipse.syson.sysml.helper.EMFUtils; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.helper.EMFUtils; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; diff --git a/backend/application/syson-application-configuration/src/test/java/org/eclipse/syson/application/services/SysONResourceServiceTests.java b/backend/application/syson-application-configuration/src/test/java/org/eclipse/syson/application/services/SysONResourceServiceTests.java index 27ee3332a..7005ebe33 100644 --- a/backend/application/syson-application-configuration/src/test/java/org/eclipse/syson/application/services/SysONResourceServiceTests.java +++ b/backend/application/syson-application-configuration/src/test/java/org/eclipse/syson/application/services/SysONResourceServiceTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2025 Obeo. + * Copyright (c) 2025, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -29,7 +29,7 @@ import org.eclipse.sirius.web.domain.boundedcontexts.semanticdata.SemanticData; import org.eclipse.syson.services.api.ISysONResourceService; import org.eclipse.syson.sysml.SysmlPackage; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.data.domain.Page; diff --git a/backend/application/syson-application/pom.xml b/backend/application/syson-application/pom.xml index aeb64a103..ceca248c4 100644 --- a/backend/application/syson-application/pom.xml +++ b/backend/application/syson-application/pom.xml @@ -1,6 +1,6 @@ org.springframework.boot diff --git a/backend/application/syson-sysml-export/src/main/java/org/eclipse/syson/sysml/export/SysMLv2DocumentExporter.java b/backend/application/syson-sysml-export/src/main/java/org/eclipse/syson/sysml/export/SysMLv2DocumentExporter.java index 425ee5698..1333302df 100644 --- a/backend/application/syson-sysml-export/src/main/java/org/eclipse/syson/sysml/export/SysMLv2DocumentExporter.java +++ b/backend/application/syson-sysml-export/src/main/java/org/eclipse/syson/sysml/export/SysMLv2DocumentExporter.java @@ -21,10 +21,10 @@ import org.eclipse.sirius.web.application.document.services.api.IDocumentExporter; import org.eclipse.syson.sysml.Element; import org.eclipse.syson.sysml.impl.MembershipCacheAdapter; -import org.eclipse.syson.sysml.textual.SysMLElementSerializer; -import org.eclipse.syson.sysml.textual.SysMLSerializingOptions; -import org.eclipse.syson.sysml.textual.utils.FileNameDeresolver; -import org.eclipse.syson.sysml.textual.utils.Status; +import org.eclipse.syson.sysml.metamodel.services.textual.SysMLElementSerializer; +import org.eclipse.syson.sysml.metamodel.services.textual.SysMLSerializingOptions; +import org.eclipse.syson.sysml.metamodel.services.textual.utils.FileNameDeresolver; +import org.eclipse.syson.sysml.metamodel.services.textual.utils.Status; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.MediaType; diff --git a/backend/application/syson-sysml-export/src/main/java/org/eclipse/syson/sysml/export/SysMLv2EditingContextPersistenceFilter.java b/backend/application/syson-sysml-export/src/main/java/org/eclipse/syson/sysml/export/SysMLv2EditingContextPersistenceFilter.java index 059e8a412..a1cb2dddc 100644 --- a/backend/application/syson-sysml-export/src/main/java/org/eclipse/syson/sysml/export/SysMLv2EditingContextPersistenceFilter.java +++ b/backend/application/syson-sysml-export/src/main/java/org/eclipse/syson/sysml/export/SysMLv2EditingContextPersistenceFilter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024, 2025 Obeo. + * Copyright (c) 2024, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -14,7 +14,7 @@ import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.sirius.web.application.editingcontext.services.api.IEditingContextPersistenceFilter; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.springframework.stereotype.Service; /** diff --git a/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/ASTTransformer.java b/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/ASTTransformer.java index 38c897125..d8ca0d958 100644 --- a/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/ASTTransformer.java +++ b/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/ASTTransformer.java @@ -27,7 +27,7 @@ import org.eclipse.sirius.components.emf.services.JSONResourceFactory; import org.eclipse.sirius.components.representations.Message; import org.eclipse.syson.services.DeleteService; -import org.eclipse.syson.sysml.helper.EMFUtils; +import org.eclipse.syson.sysml.metamodel.helper.EMFUtils; import org.eclipse.syson.sysml.parser.AstTreeParser; import org.eclipse.syson.sysml.parser.ContainmentReferenceHandler; import org.eclipse.syson.sysml.parser.EAttributeHandler; diff --git a/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/AstParsingResult.java b/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/AstParsingResult.java index 7a3c4fe3b..9412f1f4f 100644 --- a/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/AstParsingResult.java +++ b/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/AstParsingResult.java @@ -16,7 +16,7 @@ import java.util.List; import java.util.Optional; -import org.eclipse.syson.sysml.textual.utils.Status; +import org.eclipse.syson.sysml.metamodel.services.textual.utils.Status; /** * Result of the parsing of the AST. diff --git a/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/SysmlToAst.java b/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/SysmlToAst.java index 8c20eabee..a5ed0a36f 100644 --- a/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/SysmlToAst.java +++ b/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/SysmlToAst.java @@ -29,8 +29,8 @@ import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -import org.eclipse.syson.sysml.textual.utils.Severity; -import org.eclipse.syson.sysml.textual.utils.Status; +import org.eclipse.syson.sysml.metamodel.services.textual.utils.Severity; +import org.eclipse.syson.sysml.metamodel.services.textual.utils.Status; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; diff --git a/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/dto/InsertTextualSysMLv2EventHandler.java b/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/dto/InsertTextualSysMLv2EventHandler.java index 30b2ad919..2f923be72 100644 --- a/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/dto/InsertTextualSysMLv2EventHandler.java +++ b/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/dto/InsertTextualSysMLv2EventHandler.java @@ -34,7 +34,7 @@ import org.eclipse.syson.sysml.ASTTransformer; import org.eclipse.syson.sysml.Element; import org.eclipse.syson.sysml.SysmlToAst; -import org.eclipse.syson.sysml.textual.utils.Status; +import org.eclipse.syson.sysml.metamodel.services.textual.utils.Status; import org.springframework.stereotype.Service; import io.micrometer.core.instrument.Counter; diff --git a/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/parser/AstTreeParser.java b/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/parser/AstTreeParser.java index c407ac8a2..7ba4e3ab2 100644 --- a/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/parser/AstTreeParser.java +++ b/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/parser/AstTreeParser.java @@ -28,7 +28,7 @@ import org.eclipse.syson.sysml.Redefinition; import org.eclipse.syson.sysml.Specialization; import org.eclipse.syson.sysml.SysmlPackage; -import org.eclipse.syson.sysml.helper.EMFUtils; +import org.eclipse.syson.sysml.metamodel.helper.EMFUtils; import org.eclipse.syson.sysml.parser.translation.EClassifierTranslator; import org.eclipse.syson.sysml.utils.LogNameProvider; import org.eclipse.syson.sysml.utils.MessageReporter; diff --git a/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/parser/ProxyResolver.java b/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/parser/ProxyResolver.java index 300bbb85c..6a4083156 100644 --- a/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/parser/ProxyResolver.java +++ b/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/parser/ProxyResolver.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024, 2025 Obeo. + * Copyright (c) 2024, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -27,7 +27,7 @@ import org.eclipse.syson.sysml.Namespace; import org.eclipse.syson.sysml.PortDefinition; import org.eclipse.syson.sysml.SysmlPackage; -import org.eclipse.syson.sysml.helper.DeresolvingNamespaceProvider; +import org.eclipse.syson.sysml.metamodel.helper.DeresolvingNamespaceProvider; import org.eclipse.syson.sysml.utils.LogNameProvider; import org.eclipse.syson.sysml.utils.MessageReporter; import org.slf4j.Logger; diff --git a/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/upload/SysMLExternalResourceLoaderService.java b/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/upload/SysMLExternalResourceLoaderService.java index 13437bedb..bd51f11a0 100644 --- a/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/upload/SysMLExternalResourceLoaderService.java +++ b/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/upload/SysMLExternalResourceLoaderService.java @@ -33,8 +33,8 @@ import org.eclipse.syson.sysml.ASTTransformer; import org.eclipse.syson.sysml.AstParsingResult; import org.eclipse.syson.sysml.SysmlToAst; -import org.eclipse.syson.sysml.textual.utils.Status; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.services.textual.utils.Status; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; diff --git a/backend/application/syson-sysml-validation/src/main/java/org/eclipse/syson/sysml/validation/SysONSysMLValidationService.java b/backend/application/syson-sysml-validation/src/main/java/org/eclipse/syson/sysml/validation/SysONSysMLValidationService.java index 76cca95b6..83c27220d 100644 --- a/backend/application/syson-sysml-validation/src/main/java/org/eclipse/syson/sysml/validation/SysONSysMLValidationService.java +++ b/backend/application/syson-sysml-validation/src/main/java/org/eclipse/syson/sysml/validation/SysONSysMLValidationService.java @@ -29,7 +29,7 @@ import org.eclipse.sirius.components.core.api.IValidationService; import org.eclipse.sirius.components.emf.services.api.IEMFEditingContext; import org.eclipse.syson.services.api.ISysONResourceService; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; diff --git a/backend/metamodel/syson-sysml-metamodel-edit/pom.xml b/backend/metamodel/syson-sysml-metamodel-edit/pom.xml index 4cfb40af0..e9996ff77 100644 --- a/backend/metamodel/syson-sysml-metamodel-edit/pom.xml +++ b/backend/metamodel/syson-sysml-metamodel-edit/pom.xml @@ -1,6 +1,6 @@ + + org.apache.maven.plugins + maven-jar-plugin + + + + test-jar + + + + diff --git a/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/helper/DeresolvingNamespaceProvider.java b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/DeresolvingNamespaceProvider.java similarity index 99% rename from backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/helper/DeresolvingNamespaceProvider.java rename to backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/DeresolvingNamespaceProvider.java index 26168a523..2c6cf7b56 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/helper/DeresolvingNamespaceProvider.java +++ b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/DeresolvingNamespaceProvider.java @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.helper; +package org.eclipse.syson.sysml.metamodel.helper; import static java.util.stream.Collectors.toList; diff --git a/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/EMFUtils.java b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/EMFUtils.java new file mode 100644 index 000000000..1a1d8b8e9 --- /dev/null +++ b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/EMFUtils.java @@ -0,0 +1,361 @@ +/******************************************************************************* + * Copyright (c) 2024, 2026 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.syson.sysml.metamodel.helper; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.function.Predicate; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.EStructuralFeature.Setting; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.util.ECrossReferenceAdapter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Utils class to browse or edit EMF model. + * + * @author Arthur Daussy + */ +public class EMFUtils { + + private static final Logger LOGGER = LoggerFactory.getLogger(EMFUtils.class); + + /** + * Gets the ancestor of given type starting from a specific element. + * + * @param object + * an {@link EObject} + * @param type + * expected type + * @param + * expected type + * @return a expected typed ancestor or null; + */ + private static T getAncestor(Class type, EObject object) { + if (object == null) { + return null; + } + final T result; + if (type.isInstance(object)) { + result = (T) object; + } else { + result = getAncestor(type, object.eContainer()); + } + return result; + } + + /** + * Gets all Settings targeting the given source element with the given {@link EReference}. + * + * @param source + * the source element + * @param targetingFeature + * the feature that link the searched elements to the source + * @return a {@link Collection} of {@link Setting} + */ + public static Collection getInverse(EObject source, EReference targetingFeature) { + return source.eAdapters().stream() + .filter(ECrossReferenceAdapter.class::isInstance) + .map(ECrossReferenceAdapter.class::cast) + .map(crossRef -> crossRef.getInverseReferences(source, targetingFeature, false)) + .findFirst().orElseGet(() -> { + LOGGER.warn("Unable to find an ECrossReference on " + source); + return List.of(); + }); + + } + + /** + * Gets all Settings targeting the given source element. + * + * @param source + * the source element + * @return a {@link Collection} of {@link Setting} + */ + public static Collection getInverse(EObject source) { + return source.eAdapters().stream() + .filter(ECrossReferenceAdapter.class::isInstance) + .map(ECrossReferenceAdapter.class::cast) + .map(crossRef -> crossRef.getInverseReferences(source)) + .findFirst() + .orElseGet(() -> { + LOGGER.warn("Unable to find an ECrossReference on " + source); + return List.of(); + }); + + } + + /** + * Gets the first adapter of a given type installed on a Notifier. + * + * @param notifier + * notifier on which the adapter is installed + * @param adapterType + * the type of the desired adapter + * @param + * the type of the desired adapter + * @return an optional {@link Notifier} + */ + public static Optional getAdapter(Notifier notifier, Class adapterType) { + if (notifier != null) { + return notifier.eAdapters().stream() + .filter(adapterType::isInstance) + .map(adapterType::cast) + .findFirst(); + } + return Optional.empty(); + } + + /** + * Gets a stream composed from the object itself and all its content. + * + * @param o + * an {@link EObject} + * @return a stream + */ + public static Stream eAllContentStreamWithSelf(EObject o) { + if (o == null) { + return Stream.empty(); + } + return Stream.concat(Stream.of(o), StreamSupport + .stream(Spliterators.spliteratorUnknownSize(o.eAllContents(), Spliterator.NONNULL), false)); + } + + /** + * Gets a stream composed from the object itself and all its content. + * + * @param r + * a resource + * @return a stream + */ + public static Stream eAllContentStreamWithSelf(Resource r) { + if (r == null) { + return Stream.empty(); + } + return Stream.concat(Stream.of(r), StreamSupport + .stream(Spliterators.spliteratorUnknownSize(r.getAllContents(), Spliterator.NONNULL), false)); + } + + /** + * Gets a stream composed from the object itself and all its content. + * + * @param n + * a notifier + * @return a stream + */ + public static Stream eAllContentStreamWithSelf(Notifier n) { + Stream result = Stream.empty(); + if (n instanceof Resource resource) { + result = eAllContentStreamWithSelf(resource); + } else if (n instanceof EObject eObject) { + result = eAllContentStreamWithSelf(eObject).map(Notifier.class::cast); + } else if (n instanceof ResourceSet resourceSet) { + result = eAllContentStreamWithSelf(resourceSet); + } + return result; + } + + /** + * Gets a stream composed from the object itself and all its content. + * + * @param rs + * a resource set + * @return a stream + */ + public static Stream eAllContentStreamWithSelf(ResourceSet rs) { + if (rs == null) { + return Stream.empty(); + } + return Stream.concat(Stream.of(rs), StreamSupport + .stream(Spliterators.spliteratorUnknownSize(rs.getAllContents(), Spliterator.NONNULL), false)); + } + + /** + * Gets all objects contained in the given notifier with the given type. + *

+ * If self if of the expected type then it belong to the returned stream + *

+ * + * @param self + * a {@link Notifier} (EObject, Resource or ResourceSet) + * @param type + * the type of the element in the returned stream + * @return a stream + * @param + * type of element in the returned stream + */ + public static Stream allContainedObjectOfType(Notifier self, Class type) { + final Stream result; + if (self instanceof EObject eObject) { + result = eAllContentStreamWithSelf(eObject).filter(e -> type.isInstance(e)).map(e -> type.cast(e)); + } else if (self instanceof Resource resource) { + result = eAllContentStreamWithSelf(resource).filter(e -> type.isInstance(e)).map(e -> type.cast(e)); + } else if (self instanceof ResourceSet resourceSet) { + result = eAllContentStreamWithSelf(resourceSet).filter(e -> type.isInstance(e)) + .map(e -> type.cast(e)); + } else { + result = Stream.empty(); + } + return result; + } + + /** + * Returns {@code true} if {@code parent} is an ancestor of {@code eObject}. + *

+ * This method includes {@code eObject} as an ancestor of itself. This means that this method will always return + * {@code true} if {@code parent == eObject}. + *

+ * + * @param parent + * the parent EObject to check + * @param eObject + * the EObject to check + * @return {@code true} if {@code parent} is an ancestor of {@code eObject} + */ + public static boolean isAncestor(EObject parent, EObject eObject) { + return !getAncestors(EObject.class, eObject, ancestor -> Objects.equals(ancestor, parent)).isEmpty(); + } + + /** + * Gets the first ancestor from the given object which match the predicated and has the expected type. + * + * @param + * the expected type + * @param type + * the expected type + * @param object + * the source object + * @param ancestorPredicate + * an optional {@link Predicate} + * @return an ancestor or null + */ + public static List getAncestors(Class type, EObject object, Predicate ancestorPredicate) { + var current = object; + List results = new ArrayList<>(); + while (current != null) { + if (type.isInstance(current) && (ancestorPredicate == null || ancestorPredicate.test(current))) { + results.add((T) current); + } + current = current.eContainer(); + } + return results; + } + + /** + * Gets the first ancestor containing the given object with the expected type. An optional predicate can be + * specified to add more constraint on the searched ancestor.. + * + * @param + * the expected type of the ancestor + * @param type + * the expected type of the ancestor + * @param object + * the source object + * @param ancestorPredicate + * an optional predicate than can be used to add another constraint on the searched ancestor (set to + * null if the type constraint is enough) + * @return a matching ancestor or {@link Optional#empty()} + */ + public static Optional getFirstAncestor(Class type, EObject object, Predicate ancestorPredicate) { + var current = object; + while (current != null) { + if (type.isInstance(current) && (ancestorPredicate == null || ancestorPredicate.test(current))) { + return Optional.of((T) current); + } + current = current.eContainer(); + } + return Optional.empty(); + } + + /** + * Gets all the ancestors of the given object which have the expected type. + * + * @param + * the expected type + * @param type + * the expected type + * @param object + * the source object + * @return a list of ancestors + */ + private static List getAncestors(Class type, EObject object) { + return getAncestors(type, object, null); + } + + /** + * Gets the first common ancestor from both given objects with the expected type. + * + * @param + * the expected ancestor type + * @param expectedType + * the expected ancestor type + * @param e1 + * the first {@link EObject} + * @param e2 + * the last {@link EObject} + * @return an ancestor or null + */ + public static T getLeastCommonContainer(Class expectedType, EObject e1, EObject e2) { + + List e1Ancestors = getAncestors(expectedType, e1); + List e2CommonAncestors = getAncestors(expectedType, e2, container -> e1Ancestors.contains(container)); + if (e2CommonAncestors.isEmpty()) { + return null; + } else { + return e2CommonAncestors.get(0); + } + } + + /** + * Resolve all non derived references in the given {@link ResourceSet}. + * + * @param rs + * the given {@link ResourceSet}. + */ + public static void resolveAllNonDerived(ResourceSet rs) { + List resources = rs.getResources(); + for (int i = 0; i < resources.size(); i++) { + resolveAllNonDerived(resources.get(i)); + } + } + + private static void resolveAllNonDerived(Resource resource) { + resource.getContents().forEach(eObject -> resolveAllNonDerived(eObject)); + } + + private static void resolveAllNonDerived(EObject eObject) { + resolveNonDerivedCrossReferences(eObject); + for (Iterator i = eObject.eAllContents(); i.hasNext(); ) { + EObject childEObject = i.next(); + resolveNonDerivedCrossReferences(childEObject); + } + } + + private static void resolveNonDerivedCrossReferences(EObject eObject) { + eObject.eClass().getEAllReferences().stream().filter(e -> !e.isDerived() && !e.isContainment()).forEach(ref -> eObject.eGet(ref, true)); + } +} diff --git a/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/ImplicitSpecializationAccumulator.java b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/ImplicitSpecializationAccumulator.java new file mode 100644 index 000000000..56a305f2a --- /dev/null +++ b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/ImplicitSpecializationAccumulator.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2025, 2026 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.syson.sysml.metamodel.helper; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.syson.sysml.FeatureTyping; +import org.eclipse.syson.sysml.Redefinition; +import org.eclipse.syson.sysml.ReferenceSubsetting; +import org.eclipse.syson.sysml.Specialization; +import org.eclipse.syson.sysml.Subclassification; +import org.eclipse.syson.sysml.Subsetting; + +/** + * Accumulator of {@link Specialization} that keeps track of the type of the added {@link Specialization}. + * + * @author Arthur Daussy + */ +public class ImplicitSpecializationAccumulator { + + private boolean hasSubSetting; + + private boolean hasRedefinition; + + private boolean hasSubclassification; + + private boolean hasFeatureTyping; + + private final List accumulator = new ArrayList<>(); + + public ImplicitSpecializationAccumulator(boolean hasSubSetting, boolean hasRedefinition, boolean hasSubclassification, boolean hasFeatureTyping) { + super(); + this.hasSubSetting = hasSubSetting; + this.hasRedefinition = hasRedefinition; + this.hasSubclassification = hasSubclassification; + this.hasFeatureTyping = hasFeatureTyping; + } + + public static ImplicitSpecializationAccumulator fromExistingSpecialization(List specialization) { + boolean hasSubSetting = false; + boolean hasRedefinition = false; + boolean hasSubclassification = false; + boolean hasFeatureTyping = false; + + for (Specialization s : specialization) { + if (!hasSubSetting && s instanceof Subsetting && !(s instanceof Redefinition) && !(s instanceof ReferenceSubsetting)) { + hasSubSetting = true; + } + if (!hasRedefinition && s instanceof Redefinition) { + hasRedefinition = true; + } + if (!hasSubclassification && s instanceof Subclassification) { + hasSubclassification = true; + } + if (!hasFeatureTyping && s instanceof FeatureTyping) { + hasFeatureTyping = true; + } + } + return new ImplicitSpecializationAccumulator(hasSubSetting, hasRedefinition, hasSubclassification, hasFeatureTyping); + } + + public void addAll(List specializations) { + for (Specialization s : specializations) { + this.add(s); + } + } + + public boolean hasSubSetting() { + return this.hasSubSetting; + } + + public boolean hasRedefinition() { + return this.hasRedefinition; + } + + public boolean hasSubclassification() { + return this.hasSubclassification; + } + + public boolean hasFeatureTyping() { + return this.hasFeatureTyping; + } + + public List getSpecializations() { + return this.accumulator; + } + + public void add(Specialization s) { + if (!this.hasSubSetting && s instanceof Subsetting && !(s instanceof Redefinition) && !(s instanceof ReferenceSubsetting)) { + this.hasSubSetting = true; + } + if (!this.hasRedefinition && s instanceof Redefinition) { + this.hasRedefinition = true; + } + if (!this.hasSubclassification && s instanceof Subclassification) { + this.hasSubclassification = true; + } + if (!this.hasFeatureTyping && s instanceof FeatureTyping) { + this.hasFeatureTyping = true; + } + this.accumulator.add(s); + } + +} diff --git a/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/ImplicitSpecializationSwitch.java b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/ImplicitSpecializationSwitch.java new file mode 100644 index 000000000..9b320b46d --- /dev/null +++ b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/ImplicitSpecializationSwitch.java @@ -0,0 +1,1652 @@ +/******************************************************************************* + * Copyright (c) 2024, 2026 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.syson.sysml.metamodel.helper; + +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; +import java.util.Optional; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.syson.sysml.AcceptActionUsage; +import org.eclipse.syson.sysml.ActionDefinition; +import org.eclipse.syson.sysml.ActionUsage; +import org.eclipse.syson.sysml.ActorMembership; +import org.eclipse.syson.sysml.AllocationDefinition; +import org.eclipse.syson.sysml.AllocationUsage; +import org.eclipse.syson.sysml.AnalysisCaseDefinition; +import org.eclipse.syson.sysml.AnalysisCaseUsage; +import org.eclipse.syson.sysml.AssertConstraintUsage; +import org.eclipse.syson.sysml.AssignmentActionUsage; +import org.eclipse.syson.sysml.AttributeUsage; +import org.eclipse.syson.sysml.Behavior; +import org.eclipse.syson.sysml.CalculationDefinition; +import org.eclipse.syson.sysml.CalculationUsage; +import org.eclipse.syson.sysml.CaseDefinition; +import org.eclipse.syson.sysml.CaseUsage; +import org.eclipse.syson.sysml.Classifier; +import org.eclipse.syson.sysml.ConcernDefinition; +import org.eclipse.syson.sysml.ConcernUsage; +import org.eclipse.syson.sysml.ConnectionDefinition; +import org.eclipse.syson.sysml.ConnectionUsage; +import org.eclipse.syson.sysml.Connector; +import org.eclipse.syson.sysml.ConstraintDefinition; +import org.eclipse.syson.sysml.ConstraintUsage; +import org.eclipse.syson.sysml.ControlNode; +import org.eclipse.syson.sysml.DecisionNode; +import org.eclipse.syson.sysml.Definition; +import org.eclipse.syson.sysml.Element; +import org.eclipse.syson.sysml.EndFeatureMembership; +import org.eclipse.syson.sysml.EventOccurrenceUsage; +import org.eclipse.syson.sysml.ExhibitStateUsage; +import org.eclipse.syson.sysml.Expression; +import org.eclipse.syson.sysml.Feature; +import org.eclipse.syson.sysml.FeatureTyping; +import org.eclipse.syson.sysml.FeatureValue; +import org.eclipse.syson.sysml.FlowDefinition; +import org.eclipse.syson.sysml.FlowUsage; +import org.eclipse.syson.sysml.ForLoopActionUsage; +import org.eclipse.syson.sysml.ForkNode; +import org.eclipse.syson.sysml.FramedConcernMembership; +import org.eclipse.syson.sysml.IfActionUsage; +import org.eclipse.syson.sysml.IncludeUseCaseUsage; +import org.eclipse.syson.sysml.InterfaceDefinition; +import org.eclipse.syson.sysml.InterfaceUsage; +import org.eclipse.syson.sysml.ItemDefinition; +import org.eclipse.syson.sysml.ItemUsage; +import org.eclipse.syson.sysml.JoinNode; +import org.eclipse.syson.sysml.Membership; +import org.eclipse.syson.sysml.MergeNode; +import org.eclipse.syson.sysml.MetadataAccessExpression; +import org.eclipse.syson.sysml.MetadataDefinition; +import org.eclipse.syson.sysml.MetadataUsage; +import org.eclipse.syson.sysml.Multiplicity; +import org.eclipse.syson.sysml.Namespace; +import org.eclipse.syson.sysml.OccurrenceDefinition; +import org.eclipse.syson.sysml.OccurrenceUsage; +import org.eclipse.syson.sysml.OperatorExpression; +import org.eclipse.syson.sysml.PartDefinition; +import org.eclipse.syson.sysml.PartUsage; +import org.eclipse.syson.sysml.PerformActionUsage; +import org.eclipse.syson.sysml.PortDefinition; +import org.eclipse.syson.sysml.PortUsage; +import org.eclipse.syson.sysml.PortionKind; +import org.eclipse.syson.sysml.Redefinition; +import org.eclipse.syson.sysml.ReferenceSubsetting; +import org.eclipse.syson.sysml.ReferenceUsage; +import org.eclipse.syson.sysml.Relationship; +import org.eclipse.syson.sysml.RenderingDefinition; +import org.eclipse.syson.sysml.RenderingUsage; +import org.eclipse.syson.sysml.RequirementConstraintKind; +import org.eclipse.syson.sysml.RequirementConstraintMembership; +import org.eclipse.syson.sysml.RequirementDefinition; +import org.eclipse.syson.sysml.RequirementUsage; +import org.eclipse.syson.sysml.RequirementVerificationMembership; +import org.eclipse.syson.sysml.SendActionUsage; +import org.eclipse.syson.sysml.Specialization; +import org.eclipse.syson.sysml.StakeholderMembership; +import org.eclipse.syson.sysml.StateDefinition; +import org.eclipse.syson.sysml.StateSubactionKind; +import org.eclipse.syson.sysml.StateSubactionMembership; +import org.eclipse.syson.sysml.StateUsage; +import org.eclipse.syson.sysml.Step; +import org.eclipse.syson.sysml.Subclassification; +import org.eclipse.syson.sysml.Subsetting; +import org.eclipse.syson.sysml.SuccessionAsUsage; +import org.eclipse.syson.sysml.SuccessionFlowUsage; +import org.eclipse.syson.sysml.SysmlFactory; +import org.eclipse.syson.sysml.TransitionUsage; +import org.eclipse.syson.sysml.TriggerInvocationExpression; +import org.eclipse.syson.sysml.TriggerKind; +import org.eclipse.syson.sysml.Type; +import org.eclipse.syson.sysml.Usage; +import org.eclipse.syson.sysml.UseCaseDefinition; +import org.eclipse.syson.sysml.UseCaseUsage; +import org.eclipse.syson.sysml.VerificationCaseDefinition; +import org.eclipse.syson.sysml.VerificationCaseUsage; +import org.eclipse.syson.sysml.ViewDefinition; +import org.eclipse.syson.sysml.ViewRenderingMembership; +import org.eclipse.syson.sysml.ViewUsage; +import org.eclipse.syson.sysml.ViewpointDefinition; +import org.eclipse.syson.sysml.ViewpointUsage; +import org.eclipse.syson.sysml.WhileLoopActionUsage; +import org.eclipse.syson.sysml.util.ILibraryNamespaceProvider; +import org.eclipse.syson.sysml.util.SysmlSwitch; + +/** + * Switch allowing to compute implicit specializations for a given Element. + * + * @author arichard + */ +public class ImplicitSpecializationSwitch extends SysmlSwitch> { + + private final ImplicitSpecializationAccumulator implicitSpecializations; + + private final ILibraryNamespaceProvider namespaceProvider; + + public ImplicitSpecializationSwitch(List existingSpecializations, ILibraryNamespaceProvider namespaceProvider) { + this.namespaceProvider = namespaceProvider; + this.implicitSpecializations = ImplicitSpecializationAccumulator.fromExistingSpecialization(existingSpecializations); + } + + @Override + public List doSwitch(EObject eObject) { + super.doSwitch(eObject); + return this.implicitSpecializations.getSpecializations(); + } + + @Override + public List caseAcceptActionUsage(AcceptActionUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + String implicitElement = null; + if (object.isIsComposite() && object.isSubactionUsage() && !object.isTriggerAction()) { + // A composite AcceptActionUsage that is a subaction usage, but is not the triggerAction of a + // TransitionUsage, must directly or indirectly specialize the + // ActionUsageActions::Action::acceptSubactions from the Systems Model Library. + implicitElement = "Actions::Action::acceptSubactions"; + } else if (!object.isTriggerAction()) { + // An AcceptActionUsage that is not the triggerAction of a TransitionUsage must directly or indirectly + // specialize the ActionUsage Actions::acceptActions from the Systems Model Library. + implicitElement = "Actions::acceptActions"; + } else if (object.isTriggerAction()) { + // An AcceptActionUsage that is the triggerAction of TransitionUsage must directly or indirectly + // specialize the ActionUsage Actions::TransitionAction::accepter from the Systems Model Library. + implicitElement = "Actions::TransitionAction::accepter"; + } + if (implicitElement != null) { + var implicitSubsetting = this.implicitSubsetting(object, implicitElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseReferenceUsage(ReferenceUsage referenceUsage) { + + Type owningType = referenceUsage.getOwningType(); + if (owningType instanceof SuccessionAsUsage successionAsUsage) { + this.implicitSpecializations.addAll(this.handleReferenceUsageInSuccessionAsUsage(referenceUsage, successionAsUsage)); + } + + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseActionDefinition(ActionDefinition object) { + if (!this.implicitSpecializations.hasSubclassification()) { + var implicitSubclassification = this.implicitSubclassification(object, "Actions::Action"); + if (implicitSubclassification != null) { + this.implicitSpecializations.add(implicitSubclassification); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseActionUsage(ActionUsage object) { + var implicitSubsettingElement = "Actions::actions"; + // A composite ActionUsage whose owningType is PartDefinition or PartUsage must directly or indirectly + // specialize the ActionUsage Parts::Part::ownedActions from the Systems Model Library. + var owningType = object.getOwningType(); + var owningFeatureMembership = object.getOwningFeatureMembership(); + if (owningFeatureMembership instanceof StateSubactionMembership ssm && !this.implicitSpecializations.hasRedefinition()) { + // An ActionUsage that is the entry, do, or exit Action of a StateDefinition or StateUsage must redefine the + // entryAction, doAction, or exitAction feature, respectively, of the StateDefinition States::StateAction + // from the Systems Model Library. + var implicitRedefinitionElement = "States::StateAction::exitAction"; + var kind = ssm.getKind(); + if (kind == StateSubactionKind.ENTRY) { + implicitRedefinitionElement = "States::StateAction::entryAction"; + } else if (kind == StateSubactionKind.DO) { + implicitRedefinitionElement = "States::StateAction::doAction"; + } + var implicitRedefinition = this.implicitRedefinition(object, implicitRedefinitionElement); + if (implicitRedefinition != null) { + this.implicitSpecializations.add(implicitRedefinition); + } + } else if (object.isIsComposite() && (owningType instanceof PartDefinition || owningType instanceof PartUsage)) { + implicitSubsettingElement = "Parts::Part::ownedActions"; + } else if (object.isIsComposite() && object.isSubactionUsage()) { + // A composite ActionUsage that is a subaction usage must directly or indirectly specialize the ActionUsage + // Actions::Action::subactions from the Systems Model Library. + implicitSubsettingElement = "Actions::Action::subactions"; + } + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseAllocationDefinition(AllocationDefinition object) { + if (!this.implicitSpecializations.hasSubclassification()) { + var implicitSubclassification = this.implicitSubclassification(object, "Allocations::Allocation"); + if (implicitSubclassification != null) { + this.implicitSpecializations.add(implicitSubclassification); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseAllocationUsage(AllocationUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsetting = this.implicitSubsetting(object, "Allocations::allocations"); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseAnalysisCaseDefinition(AnalysisCaseDefinition object) { + if (!this.implicitSpecializations.hasSubclassification()) { + var implicitSubclassification = this.implicitSubclassification(object, "AnalysisCases::AnalysisCase"); + if (implicitSubclassification != null) { + this.implicitSpecializations.add(implicitSubclassification); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseAnalysisCaseUsage(AnalysisCaseUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "AnalysisCases::analysisCases"; + // A composite AnalysisCaseUsage whose owningType is an AnalysisCaseDefinition or AnalysisCaseUsage must + // specialize the AnalysisCaseUsage AnalysisCases::AnalysisCase::subAnalysisCases from the Systems Model + // Library. + var owningType = object.getOwningType(); + if (owningType instanceof AnalysisCaseDefinition || owningType instanceof AnalysisCaseUsage) { + implicitSubsettingElement = "AnalysisCases::AnalysisCase::subAnalysisCases"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseAssertConstraintUsage(AssertConstraintUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "Constraints::assertedConstraints"; + // If a AssertConstraintUsage is negated, then it must directly or indirectly specialize the ConstraintUsage + // Constraints::negatedConstraints. Otherwise, it must directly or indirectly specialize the ConstraintUsage + // Constraints::assertedConstraints. + if (object.isIsNegated()) { + implicitSubsettingElement = "Constraints::negatedConstraints"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseAssignmentActionUsage(AssignmentActionUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "Actions::assignmentActions"; + // A composite AssignmentActionUsage that is a subaction usage must directly or indirectly specialize the + // ActionUsage Actions::Action::assignments from the Systems Model Library. + if (object.isIsComposite() && object.isSubactionUsage()) { + implicitSubsettingElement = "Actions::Action::assignments"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseAttributeUsage(AttributeUsage object) { + if (this.implicitSpecializations.hasSubSetting()) { + var implicitSubsetting = this.implicitSubsetting(object, "Base::dataValues"); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseCalculationDefinition(CalculationDefinition object) { + if (!this.implicitSpecializations.hasSubclassification()) { + var implicitSubclassification = this.implicitSubclassification(object, "Calculations::Calculation"); + if (implicitSubclassification != null) { + this.implicitSpecializations.add(implicitSubclassification); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseCalculationUsage(CalculationUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "Calculations::calculations"; + var owningType = object.getOwningType(); + if (owningType instanceof CalculationDefinition || owningType instanceof CalculationUsage) { + implicitSubsettingElement = "Calculations::Calculation::subcalculations"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseCaseDefinition(CaseDefinition object) { + if (!this.implicitSpecializations.hasSubclassification()) { + var implicitSubclassification = this.implicitSubclassification(object, "Cases::Case"); + if (implicitSubclassification != null) { + this.implicitSpecializations.add(implicitSubclassification); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseCaseUsage(CaseUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "Cases::cases"; + // A composite CaseUsage whose owningType is a CaseDefinition or CaseUsage must directly or indirectly + // specialize the CaseUsage Cases::Case::subcases. + var owningType = object.getOwningType(); + if (owningType instanceof CaseDefinition || owningType instanceof CaseUsage) { + implicitSubsettingElement = "Cases::Case::subcases"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseConcernDefinition(ConcernDefinition object) { + if (!this.implicitSpecializations.hasSubclassification()) { + var implicitSubclassification = this.implicitSubclassification(object, "Requirements::ConcernCheck"); + if (implicitSubclassification != null) { + this.implicitSpecializations.add(implicitSubclassification); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseConcernUsage(ConcernUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "Requirements::concernChecks"; + // If a ConcernUsage is owned via a FramedConcernMembership, then it must directly or indirectly specialize + // the ConcernUsage Requirements::RequirementCheck::concerns from the Systems Model Library. + var owningFeatureMembership = object.getOwningFeatureMembership(); + if (owningFeatureMembership instanceof FramedConcernMembership) { + implicitSubsettingElement = "Requirements::RequirementCheck::concerns"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseConnectionDefinition(ConnectionDefinition object) { + if (!this.implicitSpecializations.hasSubclassification()) { + var implicitSubclassificationElement = "Connections::Connection"; + // A binary ConnectionDefinition must directly or indirectly specialize the ConnectionDefinition + // Connections::BinaryConnection from the Systems Model Library. + if (object.getOwnedEndFeature().size() == 2) { + implicitSubclassificationElement = "Connections::BinaryConnection"; + } + var implicitSubclassification = this.implicitSubclassification(object, implicitSubclassificationElement); + if (implicitSubclassification != null) { + this.implicitSpecializations.add(implicitSubclassification); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseConnectionUsage(ConnectionUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "Connections::connections"; + // A binary ConnectionUsage must directly or indirectly specialize the ConnectionUsage + // Connections::binaryConnections from the Systems Model Library. + if (object.getOwnedEndFeature().size() == 2) { + implicitSubsettingElement = "Connections::binaryConnections"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseConstraintDefinition(ConstraintDefinition object) { + if (!this.implicitSpecializations.hasSubclassification()) { + var implicitSubclassification = this.implicitSubclassification(object, "Constraints::ConstraintCheck"); + if (implicitSubclassification != null) { + this.implicitSpecializations.add(implicitSubclassification); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseConstraintUsage(ConstraintUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "Constraints::constraintChecks"; + // A ConstraintUsage whose owningType is an ItemDefinition or ItemUsage must directly or indirectly + // specialize the ConstraintUsage Items::Item::checkedConstraints. + var owningType = object.getOwningType(); + if (owningType instanceof ItemDefinition || owningType instanceof ItemUsage) { + implicitSubsettingElement = "Items::Item::checkedConstraints"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + // A ConstraintUsage whose owningFeatureMembership is a RequirementConstraintMembership must directly or + // indirectly specialize on the ConstraintUsages assumptions or constraints from the onstraintDefinition + // Requirements::RequirementCheck in the Systems Model Library, depending on whether the kind of the + // RequirementConstraintMembership is assumption or requirement, respectively. + var owningFeatureMembership = object.getOwningFeatureMembership(); + if (owningFeatureMembership instanceof RequirementConstraintMembership rcm) { + var kind = rcm.getKind(); + if (kind == RequirementConstraintKind.ASSUMPTION) { + implicitSubsettingElement = "Requirements::RequirementCheck::assumptions"; + } else { + implicitSubsettingElement = "Requirements::RequirementCheck::constraints"; + } + implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseControlNode(ControlNode object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsetting = this.implicitSubsetting(object, "Action::Action::controls"); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseDecisionNode(DecisionNode object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsetting = this.implicitSubsetting(object, "Actions::Action::decisions"); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseEventOccurrenceUsage(EventOccurrenceUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + // If an EventOccurrenceUsage has an owningType that is an OccurrenceDefinition or OccurrenceUsage, then it + // must directly or indirectly specialize the Feature Occurrences::Occurrence::timeEnclosedOccurrences. + var owningType = object.getOwningType(); + if (owningType instanceof OccurrenceDefinition || owningType instanceof OccurrenceUsage) { + var implicitSubsetting = this.implicitSubsetting(object, "Occurrences::Occurrence::timeEnclosedOccurrences"); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseExhibitStateUsage(ExhibitStateUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + // If an ExhibitStateUsage has an owningType that is a PartDefinition or PartUsage, then it must directly or + // indirectly specialize the StateUsage Parts::Part::exhibitedStates. + var owningType = object.getOwningType(); + if (owningType instanceof PartDefinition || owningType instanceof PartUsage) { + var implicitSubsetting = this.implicitSubsetting(object, "Parts::Part::exhibitedStates"); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseFeature(Feature object) { + if (!this.implicitSpecializations.hasRedefinition()) { + this.implicitSpecializations.addAll(this.handleImplicitParameterRedefinition(object)); + } + // The specification states that "If the Feature has chainingFeatures, then the union also includes the types of + // the last chainingFeature".We need to implement this here in order to make inherited Feature resolvable. + // If we only implement this in "getType" of the Feature implementation the general mechanism of name resolution + // that relies on "getMembership" would fail. + // Normally the implicit typing would be present in the model (either with an implicit inheritance + // or implicit typing). But since in SysON we choose to add those "implicit" element virtually when the derived + // feature are called, we needed to find a place where this 'implicit' typing would impact both Feature.getType + // and Namespace.getMembership. implementations. + + EList chainingFeature = object.getChainingFeature(); + if (!chainingFeature.isEmpty()) { + Feature lastFeature = chainingFeature.get(chainingFeature.size() - 1); + for (Type type : lastFeature.getType()) { + FeatureTyping featureTyping = SysmlFactory.eINSTANCE.createFeatureTyping(); + this.implicitSpecializations.add(featureTyping); + featureTyping.setType(type); + featureTyping.setTypedFeature(object); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseFlowDefinition(FlowDefinition object) { + if (!this.implicitSpecializations.hasSubclassification()) { + var implicitSubclassification = this.implicitSubclassification(object, "Connections::MessageConnection"); + if (implicitSubclassification != null) { + this.implicitSpecializations.add(implicitSubclassification); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseFlowUsage(FlowUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "Connections::flowConnections"; + // If a FlowUsage has no ownedEndFeatures, then it must directly or indirectly specialize the base + // FlowUsage Connections::messageConnections from the Systems Library model. + if (object.getOwnedEndFeature().isEmpty()) { + implicitSubsettingElement = "Connections::messageConnections"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseForkNode(ForkNode object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsetting = this.implicitSubsetting(object, "Actions::Action::forks"); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseForLoopActionUsage(ForLoopActionUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "Actions::forLoopActions"; + // A composite ForLoopActionUsage that is a subaction usage must directly or indirectly specialize the + // ActionUsage Actions::Action::forLoops from the Systems Model Library. + if (object.isIsComposite() && object.isSubactionUsage()) { + implicitSubsettingElement = "Actions::Action::forLoops"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseIfActionUsage(IfActionUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "Actions::ifThenActions"; + if (object.getElseAction() != null) { + // A IfActionUsage must directly or indirectly specialize the ActionUsage Actions::ifThenActions from + // the Systems Model Library. If it has an elseAction, then it must directly or indirectly specialize + // Actions::ifThenElseActions + implicitSubsettingElement = "Actions::ifThenElseActions"; + } else if (object.isIsComposite() && object.isSubactionUsage()) { + // A composite IfActionUsage that is a subaction usage must directly or indirectly specialize the + // ActionUsage Actions::Action::ifSubactions from the Systems Model Library. + implicitSubsettingElement = "Actions::Action::ifSubactions"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseIncludeUseCaseUsage(IncludeUseCaseUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + // A IncludeUseCaseUsage whose owningType is a UseCaseDefinition or UseCaseUsage must directly or indirectly + // specialize the UseCaseUsage UseCases::UseCase::includedUseCases from the Systems Model Library. + var owningType = object.getOwningType(); + if (owningType instanceof UseCaseDefinition || owningType instanceof UseCaseUsage) { + var implicitSubsetting = this.implicitSubsetting(object, "UseCases::UseCase::includedUseCases"); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseInterfaceDefinition(InterfaceDefinition object) { + if (!this.implicitSpecializations.hasSubclassification()) { + var implicitSubclassificationElement = "Interfaces::Interface"; + // A binary InterfaceDefinition must directly or indirectly specialize the InterfaceDefinition + // Interfaces::BinaryInterface from the Systems Model Library. + if (object.getOwnedEndFeature().size() == 2) { + implicitSubclassificationElement = "Interfaces::BinaryInterface"; + } + var implicitSubclassification = this.implicitSubclassification(object, implicitSubclassificationElement); + if (implicitSubclassification != null) { + this.implicitSpecializations.add(implicitSubclassification); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseInterfaceUsage(InterfaceUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "Interfaces::interfaces"; + // A binary InterfaceUsage must directly or indirectly specialize the InterfaceUsage + // Interfaces::binaryInterfaces from the Systems Model Library. + if (object.getOwnedEndFeature().size() == 2) { + implicitSubsettingElement = "Interfaces::binaryInterfaces"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseItemDefinition(ItemDefinition object) { + if (!this.implicitSpecializations.hasSubclassification()) { + var implicitSubclassification = this.implicitSubclassification(object, "Items::Item"); + if (implicitSubclassification != null) { + this.implicitSpecializations.add(implicitSubclassification); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseItemUsage(ItemUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsetting = this.implicitSubsetting(object, "Items::items"); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseJoinNode(JoinNode object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsetting = this.implicitSubsetting(object, "Actions::Action::join"); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseMergeNode(MergeNode object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsetting = this.implicitSubsetting(object, "Actions::Action::merges"); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseMetadataDefinition(MetadataDefinition object) { + if (!this.implicitSpecializations.hasSubclassification()) { + var implicitSubclassification = this.implicitSubclassification(object, "Metadata::MetadataItem"); + if (implicitSubclassification != null) { + this.implicitSpecializations.add(implicitSubclassification); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseMetadataUsage(MetadataUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsetting = this.implicitSubsetting(object, "Metadata::metadataItems"); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseMultiplicity(Multiplicity object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsetting = this.implicitSubsetting(object, "Base::naturals"); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseOccurrenceDefinition(OccurrenceDefinition object) { + if (!this.implicitSpecializations.hasSubclassification()) { + var implicitSubclassification = this.implicitSubclassification(object, "Occurrences::Occurrence"); + if (implicitSubclassification != null) { + this.implicitSpecializations.add(implicitSubclassification); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseOccurrenceUsage(OccurrenceUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + if (PortionKind.TIMESLICE.equals(object.getPortionKind())) { + var implicitTimeSliceSubsetting = this.implicitSubsetting(object, "Occurrences::Occurrence::timeSlices"); + if (implicitTimeSliceSubsetting != null) { + this.implicitSpecializations.add(implicitTimeSliceSubsetting); + } + } else if (PortionKind.SNAPSHOT.equals(object.getPortionKind())) { + var implicitSnapshotSubsetting = this.implicitSubsetting(object, "Occurrences::Occurrence::snapshots"); + if (implicitSnapshotSubsetting != null) { + this.implicitSpecializations.add(implicitSnapshotSubsetting); + } + } else { + var implicitSubsetting = this.implicitSubsetting(object, "Occurrences::occurrences"); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + } else { + if (PortionKind.TIMESLICE.equals(object.getPortionKind())) { + // If the occurrence has subsettings and is a time slice, then we should ensure one of the subsetting specializes 'Occurrences::Occurrence::timeSlices' + object.getOwnedRelationship().stream() + .filter(Subsetting.class::isInstance) + .map(Subsetting.class::cast) + .map(Subsetting::getSubsettedFeature) + .filter(feature -> !feature.specializesFromLibrary("Occurrences::Occurrence::timeSlices")) + .findFirst() + .ifPresent(feature -> { + var implicitTimeSliceSubsetting = this.implicitSubsetting(object, "Occurrences::Occurrence::timeSlices"); + if (implicitTimeSliceSubsetting != null) { + this.implicitSpecializations.add(implicitTimeSliceSubsetting); + } + }); + } else if (PortionKind.SNAPSHOT.equals(object.getPortionKind())) { + // If the occurrence has subsettings and is a snapshot, then we should ensure one of the subsetting specializes 'Occurrences::Occurrence::snapshots' + object.getOwnedRelationship().stream() + .filter(Subsetting.class::isInstance) + .map(Subsetting.class::cast) + .map(Subsetting::getSubsettedFeature) + .filter(feature -> !feature.specializesFromLibrary("Occurrences::Occurrence::snapshots")) + .findFirst() + .ifPresent(feature -> { + var implicitTimeSliceSubsetting = this.implicitSubsetting(object, "Occurrences::Occurrence::snapshots"); + if (implicitTimeSliceSubsetting != null) { + this.implicitSpecializations.add(implicitTimeSliceSubsetting); + } + }); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List casePartDefinition(PartDefinition object) { + if (!this.implicitSpecializations.hasSubclassification()) { + var implicitSubclassification = this.implicitSubclassification(object, "Parts::Part"); + if (implicitSubclassification != null) { + this.implicitSpecializations.add(implicitSubclassification); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List casePartUsage(PartUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "Parts::parts"; + var owningType = object.getOwningType(); + if (object.getOwningFeatureMembership() instanceof ActorMembership) { + // If a PartUsage is owned via an ActorMembership, then it must directly or indirectly specialize either + // Requirements::RequirementCheck::actors (if its owningType is a RequirementDefinition or + // RequirementUsage or Cases::Case::actors (otherwise). + if (owningType instanceof RequirementDefinition || owningType instanceof RequirementUsage) { + implicitSubsettingElement = "Requirements::RequirementCheck::actors"; + } else { + implicitSubsettingElement = "Cases::Case::actors"; + } + } else if (object.getOwningFeatureMembership() instanceof StakeholderMembership) { + // If a PartUsage is owned via a StakeholderMembership, then it must directly or indirectly specialize + // either Requirements::RequirementCheck::stakeholders. + implicitSubsettingElement = "Requirements::RequirementCheck::stakeholders"; + } else if (object.isIsComposite() && (owningType instanceof ItemDefinition || owningType instanceof ItemUsage)) { + // A composite PartUsage whose owningType is a ItemDefinition or ItemUsage must directly or indirectly + // specialize the PartUsage Items::Item::subparts from the Systems Model Library. + implicitSubsettingElement = "Items::Item::subparts"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List casePerformActionUsage(PerformActionUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + // If a PerformActionUsage has an owningType that is a PartDefinition or PartUsage, then it must directly or + // indirectly specialize the ActionUsage Parts::Part::performedActions. + var owningType = object.getOwningType(); + if (owningType instanceof PartDefinition || owningType instanceof PartUsage) { + var implicitSubsetting = this.implicitSubsetting(object, "Parts::Part::performedActions"); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List casePortDefinition(PortDefinition object) { + if (!this.implicitSpecializations.hasSubclassification()) { + var implicitSubclassification = this.implicitSubclassification(object, "Ports::Port"); + if (implicitSubclassification != null) { + this.implicitSpecializations.add(implicitSubclassification); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List casePortUsage(PortUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "Ports::ports"; + // A composite PortUsage with an owningType that is a PortDefinition or PortUsage must directly or + // indirectly specialize the PortUsage Ports::Port::subports from the Systems Model Library. + var owningType = object.getOwningType(); + if (object.isIsComposite() && (owningType instanceof PortDefinition || owningType instanceof PortUsage)) { + implicitSubsettingElement = "Ports::Port::subports"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseRenderingDefinition(RenderingDefinition object) { + if (!this.implicitSpecializations.hasSubclassification()) { + var implicitSubclassification = this.implicitSubclassification(object, "Views::Rendering"); + if (implicitSubclassification != null) { + this.implicitSpecializations.add(implicitSubclassification); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseRenderingUsage(RenderingUsage object) { + var owningFeatureMembership = object.getOwningFeatureMembership(); + if (owningFeatureMembership instanceof ViewRenderingMembership && !(this.implicitSpecializations.hasRedefinition())) { + // A RenderingUsage whose owningFeatureMembership is a ViewRenderingMembership must redefine the + // RenderingUsage Views::View::viewRendering + var implicitRedefinitionElement = "Views::View::viewRendering"; + var implicitRedefinition = this.implicitRedefinition(object, implicitRedefinitionElement); + if (implicitRedefinition != null) { + this.implicitSpecializations.add(implicitRedefinition); + } + } + if (this.implicitSpecializations.getSpecializations().isEmpty()) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "Views::renderings"; + var owningType = object.getOwningType(); + if (object.isIsComposite() && (owningType instanceof RenderingDefinition || owningType instanceof RenderingUsage)) { + // A RenderingUsage whose owningType is a RenderingDefinition or RenderingUsage must directly or + // indirectly specialize the RenderingUsage Views::Rendering::subrenderings from the Systems Model + // Library. + implicitSubsettingElement = "Views::Rendering::subrenderings"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseRequirementDefinition(RequirementDefinition object) { + if (!this.implicitSpecializations.hasSubclassification()) { + var implicitSubclassification = this.implicitSubclassification(object, "Requirements::RequirementCheck"); + if (implicitSubclassification != null) { + this.implicitSpecializations.add(implicitSubclassification); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseRequirementUsage(RequirementUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "Requirements::requirementChecks"; + var owningType = object.getOwningType(); + var owningFeatureMembership = object.getOwningFeatureMembership(); + if (object.isIsComposite() && (owningType instanceof RequirementDefinition || owningType instanceof RequirementUsage)) { + // A composite RequirementUsage whose owningType is a RequirementDefinition or RequirementUsage must + // directly or indirectly specialize the RequirementUsage + // Requirements::RequirementCheck::subrequirements from the Systems Model Library. + implicitSubsettingElement = "Requirements::RequirementCheck::subrequirements"; + } else if (owningFeatureMembership instanceof RequirementVerificationMembership) { + // RequirementUsage whose owningFeatureMembership is a RequirementVerificationMembership must directly + // or indirectly specialize the RequirementUsage + // VerificationCases::VerificationCase::obj::requirementVerifications. + implicitSubsettingElement = "VerificationCases::VerificationCase::obj::requirementVerifications"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseSendActionUsage(SendActionUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "Actions::sendActions"; + // A composite SendActionUsage that is a subaction must directly or indirectly specialize the ActionUsage + // Actions::Action::sendSubactions from the Systems Model Library. + if (object.isIsComposite() && object.isSubactionUsage()) { + implicitSubsettingElement = "Actions::Action::acceptSubactions"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseStateDefinition(StateDefinition object) { + if (!this.implicitSpecializations.hasSubclassification()) { + var implicitSubclassification = this.implicitSubclassification(object, "States::StateAction"); + if (implicitSubclassification != null) { + this.implicitSpecializations.add(implicitSubclassification); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseStateUsage(StateUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "States::stateActions"; + // A StateUsage that is a substate usage with a non-parallel owning StateDefinition or StateUsage must + // directly or indirectly specialize the StateUsage States::StateAction::exclusiveStates from the Systems + // Model Library. + if (object.isSubstateUsage(false)) { + implicitSubsettingElement = "States::StateAction::exclusiveStates"; + } else if (object.isSubstateUsage(true)) { + implicitSubsettingElement = "States::StateAction::substates"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseSuccessionFlowUsage(SuccessionFlowUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsetting = this.implicitSubsetting(object, "Flows::successionFlows"); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseTransitionUsage(TransitionUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "Actions::transitionActions"; + // A composite TransitionUsage whose owningType is a ActionDefinition or ActionUsage, but not a + // StateDefinition or StateUsage, must directly or indirectly specialize the ActionUsage + // Actions::Action::decisionTransitions from the Systems Model Library. A composite TransitionUsage whose + // owningType is a StateDefinition or StateUsage must directly or indirectly specialize the ActionUsage + // States::State::stateTransitions from the Systems Model Library. + var owningType = object.getOwningType(); + if (object.isIsComposite() && (owningType instanceof ActionDefinition || owningType instanceof ActionUsage)) { + if (!(owningType instanceof StateDefinition || owningType instanceof StateUsage)) { + implicitSubsettingElement = "Actions::Action::decisionTransitions"; + } else { + implicitSubsettingElement = "States::State::stateTransitions"; + } + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseTriggerInvocationExpression(TriggerInvocationExpression object) { + if (!this.implicitSpecializations.hasSubSetting()) { + // A TriggerInvocationExpression must directly or indirectly specialize one of the Functions TriggerWhen, + // TriggerAt or TriggerAfter, from the Kernel Semantic Library Triggers package, depending on whether its + // kind is when, at or after, respectively. + var implicitSubsettingElement = "Triggers::TriggerAfter"; + if (object.getKind() == TriggerKind.WHEN) { + implicitSubsettingElement = "Triggers::TriggerWhen"; + } else if (object.getKind() == TriggerKind.AT) { + implicitSubsettingElement = "Triggers::TriggerAt"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseType(Type object) { + // Describe limitation with use of external metadata + List metadataUsage = object.getOwnedMembership().stream() + .map(Membership::getMemberElement) + .filter(MetadataUsage.class::isInstance) + .map(MetadataUsage.class::cast) + .toList(); + + // Avoid any computation if no metadata usage is defined + if (!metadataUsage.isEmpty()) { + /* + * This code gets the MetadaUsage contained inside the object. + */ + Type semanticMedatadaMetaclass = this.namespaceProvider.getNamespaceFromLibrary("Metaobjects::SemanticMetadata", Type.class); + List baseTypes = metadataUsage.stream() + .filter(MetadataUsage::isSemantic) + .flatMap(mu -> this.getBaseTypes(mu).stream()) + .toList(); + + boolean isAnnotatedTypeAUsage = object instanceof Usage; + boolean isAnnotatedTypeADefinition = object instanceof Definition; + + for (Type baseType : baseTypes) { + if (isAnnotatedTypeADefinition) { + Definition annotatedDefinition = (Definition) object; + if (baseType instanceof Classifier baseClassifier) { + this.implicitSpecializations.add(this.implicitSubclassification(annotatedDefinition, baseClassifier)); + } else if (baseType instanceof Feature baseFeature) { + baseFeature.getType().stream() + .filter(Classifier.class::isInstance) + .map(Classifier.class::cast) + .forEach(baseClassifier -> { + this.implicitSpecializations.add(this.implicitSubclassification(annotatedDefinition, baseClassifier)); + }); + } + } else if (isAnnotatedTypeAUsage) { + Usage annotatedUsage = (Usage) object; + if (baseType instanceof Feature basefeature) { + this.implicitSpecializations.add(this.implicitReferenceSubsetting(annotatedUsage, basefeature)); + } + } + } + } + + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseUseCaseDefinition(UseCaseDefinition object) { + if (!this.implicitSpecializations.hasSubclassification()) { + var implicitSubclassification = this.implicitSubclassification(object, "UseCases::UseCase"); + if (implicitSubclassification != null) { + this.implicitSpecializations.add(implicitSubclassification); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseUseCaseUsage(UseCaseUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "UseCases::useCases"; + // A composite UseCaseUsage whose owningType is a UseCaseDefinition or UseCaseUsage must specialize the + // UseCaseUsage UseCases::UseCase::subUseCases from the Systems Model Library. + var owningType = object.getOwningType(); + if (object.isIsComposite() && (owningType instanceof UseCaseDefinition || owningType instanceof UseCaseUsage)) { + implicitSubsettingElement = "UseCases::UseCase::subUseCases"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseVerificationCaseDefinition(VerificationCaseDefinition object) { + if (!this.implicitSpecializations.hasSubclassification()) { + var implicitSubclassification = this.implicitSubclassification(object, "VerificationCases::VerificationCase"); + if (implicitSubclassification != null) { + this.implicitSpecializations.add(implicitSubclassification); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseVerificationCaseUsage(VerificationCaseUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "VerificationCases::verificationCases"; + // If it is composite and owned by a VerificationCaseDefinition or VerificationCaseUsage, then it must + // specialize VerificationCaseUsage VerificationCases::VerificationCase::subVerificationCases. + var owningType = object.getOwningType(); + if (object.isIsComposite() && (owningType instanceof VerificationCaseDefinition || owningType instanceof VerificationCaseUsage)) { + implicitSubsettingElement = "VerificationCases::VerificationCase::subVerificationCases"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseViewDefinition(ViewDefinition object) { + if (!this.implicitSpecializations.hasSubclassification()) { + var implicitSubclassification = this.implicitSubclassification(object, "Views::View"); + if (implicitSubclassification != null) { + this.implicitSpecializations.add(implicitSubclassification); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseViewpointDefinition(ViewpointDefinition object) { + if (!this.implicitSpecializations.hasSubclassification()) { + var implicitSubclassification = this.implicitSubclassification(object, "Views::Viewpoint"); + if (implicitSubclassification != null) { + this.implicitSpecializations.add(implicitSubclassification); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseViewpointUsage(ViewpointUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "Views::viewpoints"; + // A composite ViewpointUsage whose owningType is a ViewDefinition or ViewUsage must directly or indirectly + // specialize the ViewpointUsage Views::View::viewpointSatisfactions from the Systems Model Library. + var owningType = object.getOwningType(); + if (object.isIsComposite() && (owningType instanceof ViewDefinition || owningType instanceof ViewUsage)) { + implicitSubsettingElement = "Views::View::viewpointSatisfactions"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseViewUsage(ViewUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "Views::views"; + // A ViewUsage whose owningType is a ViewDefinition or ViewUsage must specialize the ViewUsage + // Views::View::subviews from the Systems Library Model. + var owningType = object.getOwningType(); + if (owningType instanceof ViewDefinition || owningType instanceof ViewUsage) { + implicitSubsettingElement = "Views::View::subviews"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + @Override + public List caseWhileLoopActionUsage(WhileLoopActionUsage object) { + if (!this.implicitSpecializations.hasSubSetting()) { + var implicitSubsettingElement = "Actions::whileLoopActions"; + // A composite WhileLoopActionUsage that is a subaction usage must directly or indirectly specialize the + // ActionUsage Actions::Action::whileLoops from the Systems Model Library. + if (object.isIsComposite() && object.isSubactionUsage()) { + implicitSubsettingElement = "Actions::Action::whileLoops"; + } + var implicitSubsetting = this.implicitSubsetting(object, implicitSubsettingElement); + if (implicitSubsetting != null) { + this.implicitSpecializations.add(implicitSubsetting); + } + } + // Return null to iterate on other abstract EClass cases + return null; + } + + private List getBaseTypes(MetadataUsage metadaUsage) { + String baseTypeFeatureQn = "Metaobjects::SemanticMetadata::baseType"; + Feature baseTypeFeature = this.namespaceProvider.getNamespaceFromLibrary(baseTypeFeatureQn, Feature.class); + Expression valueExpression = metadaUsage.getMetadataDefinition().getOwnedFeature().stream() + .filter(f -> f.supertypes(true).contains(baseTypeFeature)) + .findFirst() + .map(this::getValue) + .orElse(null); + + if (valueExpression instanceof OperatorExpression opExpression && "meta".equals(opExpression.getOperator())) { + return opExpression.getParameter().stream() + .map(this::getValue) + .filter(MetadataAccessExpression.class::isInstance) + .map(MetadataAccessExpression.class::cast) + .map(MetadataAccessExpression::getReferencedElement) + .filter(Type.class::isInstance) + .map(Type.class::cast) + .toList(); + } else { + return List.of(); + } + } + + private Expression getValue(Feature f) { + return f.getOwnedMembership().stream() + .filter(FeatureValue.class::isInstance) + .map(FeatureValue.class::cast) + .findFirst() + .map(FeatureValue::getValue) + .orElse(null); + } + + private Redefinition implicitRedefinition(Feature feature, String implicitRedefinedFeatureQualifiedName) { + var implicitFeature = this.namespaceProvider.getNamespaceFromLibrary(implicitRedefinedFeatureQualifiedName, Feature.class); + if (implicitFeature != null) { + return this.implicitRedefinition(feature, implicitFeature); + } + return null; + } + + private Redefinition implicitRedefinition(Feature redefiningFeature, Feature redefinedFeature) { + var redefinition = SysmlFactory.eINSTANCE.createRedefinition(); + redefinition.setDeclaredName("redefines (implicit)"); + redefinition.setIsImplied(true); + redefinition.setRedefiningFeature(redefiningFeature); + redefinition.setRedefinedFeature(redefinedFeature); + return redefinition; + } + + private Subclassification implicitSubclassification(Classifier classifier, String implicitSuperclassifierQualifiedName) { + var implicitClassifier = this.namespaceProvider.getNamespaceFromLibrary(implicitSuperclassifierQualifiedName, Classifier.class); + if (implicitClassifier != null) { + return this.implicitSubclassification(classifier, implicitClassifier); + } + return null; + } + + private Subclassification implicitSubclassification(Classifier classifier, Classifier implicitClassifier) { + var subclassification = SysmlFactory.eINSTANCE.createSubclassification(); + subclassification.setDeclaredName("subclasses (implicit)"); + subclassification.setIsImplied(true); + subclassification.setSubclassifier(classifier); + subclassification.setSuperclassifier(implicitClassifier); + return subclassification; + } + + private Subsetting implicitSubsetting(Feature feature, String implicitSubsettedFeatureQualifiedName) { + var implicitFeature = this.namespaceProvider.getNamespaceFromLibrary(implicitSubsettedFeatureQualifiedName, Feature.class); + if (implicitFeature != null) { + return this.implicitSubsetting(feature, implicitFeature); + } + return null; + } + + private Subsetting implicitSubsetting(Feature feature, Feature implicitFeature) { + var subsetting = SysmlFactory.eINSTANCE.createSubsetting(); + subsetting.setDeclaredName("subsets (implicit)"); + subsetting.setIsImplied(true); + subsetting.setSubsettingFeature(feature); + subsetting.setSubsettedFeature(implicitFeature); + return subsetting; + } + + private Subsetting implicitReferenceSubsetting(Feature feature, Feature implicitFeature) { + var subsetting = SysmlFactory.eINSTANCE.createReferenceSubsetting(); + subsetting.setDeclaredName("subsets (implicit)"); + subsetting.setIsImplied(true); + subsetting.setSubsettingFeature(feature); + subsetting.setSubsettedFeature(implicitFeature); + return subsetting; + } + + private FeatureTyping implicitTyping(Feature feature, String implicitTypeQualifiedName) { + var implicitType = this.namespaceProvider.getNamespaceFromLibrary(implicitTypeQualifiedName, Type.class); + if (implicitType != null) { + var featureTyping = SysmlFactory.eINSTANCE.createFeatureTyping(); + featureTyping.setDeclaredName("typed by (implicit)"); + featureTyping.setIsImplied(true); + featureTyping.setTypedFeature(feature); + featureTyping.setType(implicitType); + return featureTyping; + } + return null; + } + + /** + * Handle special case of {@link ReferenceUsage} inside the {@link EndFeatureMembership} of a + * {@link SuccessionAsUsage}. + * + *

+ * The first two ReferenceUsage of a SuccessionAsUsage point to the source and target. If those ReferenceUsages do + * not explicitly define a {@link ReferenceSubsetting} then a {@link ReferenceSubsetting} is computed from the + * previous and next feature. + *

+ * + * @param referenceUsage + * the {@link ReferenceUsage} that might need modificationU + * @param parentSuccessionAsUsage + * the parent element of the given {@link ReferenceUsage} + * @return a list of {@link Specialization} + */ + private List handleReferenceUsageInSuccessionAsUsage(ReferenceUsage referenceUsage, SuccessionAsUsage parentSuccessionAsUsage) { + final List result; + // At this moment we only handle the case of implicit source since we haven't found a + // case where the target is implicit + int index = parentSuccessionAsUsage.getOwnedFeature().indexOf(referenceUsage); + boolean hasNoExpliciteSubsetting = this.getOwnedRelations(ReferenceSubsetting.class, referenceUsage).isEmpty(); + if (index == 0 && this.getOwnedRelations(ReferenceSubsetting.class, referenceUsage).isEmpty()) { + // Source feature + // Add a reference ReferenceSubsetting to the previous feature + Feature sourceFeature = this.computeSourceFeature(parentSuccessionAsUsage); + result = List.of(this.implicitReferenceSubsetting(referenceUsage, sourceFeature)); + } else if (index == 1 && hasNoExpliciteSubsetting) { + // Target feature + // Add a reference ReferenceSubsetting to the next feature + Feature targetFeature = this.computeTargetFeature(parentSuccessionAsUsage); + result = List.of(this.implicitReferenceSubsetting(referenceUsage, targetFeature)); + } else { + result = List.of(); + } + return result; + } + + private List getOwnedRelations(java.lang.Class type, Element parent) { + return parent.getOwnedRelationship().stream() + .filter(type::isInstance) + .map(type::cast) + .toList(); + } + + private Feature computeSourceFeature(SuccessionAsUsage successionAsUsage) { + Feature computeSourceFeature = null; + Namespace owningNamespace = successionAsUsage.getOwningNamespace(); + if (owningNamespace instanceof TransitionUsage transitionUsage && transitionUsage.getSuccession() == successionAsUsage) { + computeSourceFeature = transitionUsage.getSource(); + } else if (owningNamespace != null) { + EList ownedMemberships = owningNamespace.getOwnedMembership(); + int index = ownedMemberships.indexOf(successionAsUsage.getOwningMembership()); + if (index > 0) { + ListIterator iterator = ownedMemberships.subList(0, index).listIterator(index); + while (iterator.hasPrevious()) { + Membership previous = iterator.previous(); + if (previous.getMemberElement() instanceof Feature feature && this.isValidSourceOrTargetFeaturForSuccession(feature)) { + return feature; + } + } + } + } + return computeSourceFeature; + } + + private Feature computeTargetFeature(SuccessionAsUsage successionAsUsage) { + Feature computeTargetFeature = null; + Namespace owningNamespace = successionAsUsage.getOwningNamespace(); + if (owningNamespace instanceof TransitionUsage transitionUsage && transitionUsage.getSuccession() == successionAsUsage) { + computeTargetFeature = transitionUsage.getTarget(); + } else if (owningNamespace != null) { + EList ownedMemberships = owningNamespace.getOwnedMembership(); + int index = ownedMemberships.indexOf(successionAsUsage.getOwningMembership()); + if (index > 0 && ownedMemberships.size() > index) { + ListIterator iterator = ownedMemberships.subList(index + 1, ownedMemberships.size()).listIterator(); + while (iterator.hasNext()) { + Membership next = iterator.next(); + if (next.getMemberElement() instanceof Feature feature && this.isValidSourceOrTargetFeaturForSuccession(feature)) { + return feature; + } + } + } + } + return computeTargetFeature; + } + + private boolean isValidSourceOrTargetFeaturForSuccession(Feature feature) { + return !(feature instanceof Connector || feature instanceof TransitionUsage); + } + + /** + * Handle the creation of implicit redefinitions for feature that are parameters of their owner. + *

+ * This method implements KerML 7.4.7.2 and 7.4.7.3, and ensures that a parameter implicitly redefines the + * corresponding parameters of its owner's specializations that are {@link Behavior} or {@link Step}. + *

+ * + * @param feature + * the feature to redefine + * @return the list of {@link Redefinition} for the provided {@code feature} + */ + private List handleImplicitParameterRedefinition(Feature feature) { + List implicitRedefinitions = new ArrayList<>(); + if (feature.getOwner() instanceof Step stepOwner) { + implicitRedefinitions = this.handleImplicitParameterRedefinition(feature, stepOwner); + } else if (feature.getOwner() instanceof Behavior behaviorOwner) { + implicitRedefinitions = this.handleImplicitParameterRedefinition(feature, behaviorOwner); + } + return implicitRedefinitions; + } + + private List handleImplicitParameterRedefinition(Feature feature, Step owner) { + List implicitRedefinitions = new ArrayList<>(); + int parameterIndex = owner.getParameter().indexOf(feature); + if (parameterIndex >= 0) { + implicitRedefinitions = owner.getOwnedSpecialization().stream() + .map(Specialization::getGeneral) + .filter(type -> type instanceof Behavior || type instanceof Step) + .map(type -> this.createImplicitParameterRedefinition(feature, type, parameterIndex)) + .filter(Optional::isPresent) + .map(Optional::get) + .toList(); + } + return implicitRedefinitions; + } + + private List handleImplicitParameterRedefinition(Feature feature, Behavior owner) { + List implicitRedefinitions = new ArrayList<>(); + int parameterIndex = owner.getParameter().indexOf(feature); + if (parameterIndex >= 0) { + implicitRedefinitions = owner.getOwnedSubclassification().stream() + .map(Subclassification::getSuperclassifier) + .filter(Behavior.class::isInstance) + .map(classifier -> this.createImplicitParameterRedefinition(feature, classifier, parameterIndex)) + .filter(Optional::isPresent) + .map(Optional::get) + .toList(); + } + return implicitRedefinitions; + } + + /** + * Creates an implicit redefinition from {@code feature} to the {@code index} parameter of {@code type}. + *

+ * This method creates the redefinition if: + *

    + *
  • The provided {@code type} contains parameters
  • + *
  • The {@code index} parameter of {@code type} exists
  • + *
  • The {@code index} parameter of {@code type} has the same direction as the provided {@code feature}.
  • + *
+ *

+ * + * @param feature + * the feature redefining the parameter + * @param type + * the type containing the redefined parameter + * @param index + * the index of the redefined parameter in {@code type} + * @return + */ + private Optional createImplicitParameterRedefinition(Feature feature, Type type, int index) { + Optional result = Optional.empty(); + List parameters = new ArrayList<>(); + if (type instanceof Behavior behavior) { + parameters = behavior.getParameter(); + } else if (type instanceof Step step) { + parameters = step.getParameter(); + } + if (parameters.size() > index) { + if (parameters.get(index).getDirection() == feature.getDirection()) { + result = Optional.ofNullable(this.implicitRedefinition(feature, parameters.get(index))); + } + } + return result; + } +} diff --git a/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/LabelConstants.java b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/LabelConstants.java new file mode 100644 index 000000000..44d2702ee --- /dev/null +++ b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/LabelConstants.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2023, 2026 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.syson.sysml.metamodel.helper; + +import org.eclipse.syson.sysml.metamodel.services.textual.SysMLv2Keywords; + +/** + * Label-related constants. + * + * @author arichard + */ +public class LabelConstants { + + public static final String ABSTRACT = SysMLv2Keywords.ABSTRACT; + + public static final String CLOSE_BRACKET = SysMLv2Keywords.RIGHT_BRACKET; + + public static final String CLOSE_PARENTHESIS = SysMLv2Keywords.RIGHT_PAREN; + + public static final String CLOSE_QUOTE = "\u00BB"; + + public static final String COLON = SysMLv2Keywords.COLON; + + public static final String COLON_EQUAL = SysMLv2Keywords.ASSIGNMENT; + + public static final String COMMA = SysMLv2Keywords.COMMA; + + public static final String CONJUGATED = SysMLv2Keywords.TILDE; + + public static final String CONSTANT = SysMLv2Keywords.CONSTANT; + + public static final String CR = "\n"; + + public static final String DEFAULT = SysMLv2Keywords.DEFAULT; + + public static final String DERIVED = SysMLv2Keywords.DERIVED; + + public static final String END = SysMLv2Keywords.END; + + public static final String EQUAL = SysMLv2Keywords.EQUALS; + + public static final String FRAME = SysMLv2Keywords.FRAME; + + public static final String GREATER_THAN = SysMLv2Keywords.GREATER_THAN; + + public static final String IN = SysMLv2Keywords.IN; + + public static final String INOUT = SysMLv2Keywords.INOUT; + + public static final String LESSER_THAN = SysMLv2Keywords.LESS_THAN; + + public static final String NON_UNIQUE = SysMLv2Keywords.NONUNIQUE; + + public static final String OPEN_BRACKET = SysMLv2Keywords.LEFT_BRACKET; + + public static final String OPEN_PARENTHESIS = SysMLv2Keywords.LEFT_PAREN; + + public static final String OPEN_QUOTE = "\u00AB"; + + public static final String ORDERED = SysMLv2Keywords.ORDERED; + + public static final String OUT = SysMLv2Keywords.OUT; + + public static final String REDEFINITION = SysMLv2Keywords.REDEFINES_OPERATOR; + + public static final String REF = SysMLv2Keywords.REF; + + public static final String REFERENCES = SysMLv2Keywords.DOUBLE_COLON_SPECIALIZES; + + public static final String SATISFY = SysMLv2Keywords.SATISFY; + + public static final String SPACE = " "; + + public static final String SUBCLASSIFICATION = SysMLv2Keywords.SPECIALIZES_OPERATOR; + + public static final String SUBSETTING = SysMLv2Keywords.SPECIALIZES_OPERATOR; + + public static final String TIMESLICE = SysMLv2Keywords.TIMESLICE; + + public static final String SNAPSHOT = SysMLv2Keywords.SNAPSHOT; + + public static final String VARIANT = SysMLv2Keywords.VARIANT; + + public static final String VARIATION = SysMLv2Keywords.VARIATION; +} diff --git a/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/MembershipComputer.java b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/MembershipComputer.java new file mode 100644 index 000000000..29fdc15aa --- /dev/null +++ b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/MembershipComputer.java @@ -0,0 +1,199 @@ +/******************************************************************************* + * Copyright (c) 2024, 2026 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.syson.sysml.metamodel.helper; + +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toSet; + +import java.util.List; +import java.util.Set; +import java.util.stream.Stream; + +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.util.EcoreEList; +import org.eclipse.syson.sysml.Conjugation; +import org.eclipse.syson.sysml.Element; +import org.eclipse.syson.sysml.Import; +import org.eclipse.syson.sysml.Membership; +import org.eclipse.syson.sysml.MembershipImport; +import org.eclipse.syson.sysml.Namespace; +import org.eclipse.syson.sysml.NamespaceImport; +import org.eclipse.syson.sysml.Specialization; +import org.eclipse.syson.sysml.SysmlPackage; +import org.eclipse.syson.sysml.Type; +import org.eclipse.syson.sysml.VisibilityKind; + +/** + * Object in charge of computing. + *
    + *
  • visibleMemberships
  • + *
  • inheritedMemberships
  • + *
  • importedMemberships
  • + *
+ * + * @param + * the type on which to apply the computation + * @author Arthur Daussy + */ +public class MembershipComputer { + + private final Set visited; + + private final T sourceElement; + + public MembershipComputer(T sourceElement, EList excluded) { + this.visited = excluded.stream().collect(toSet()); + this.sourceElement = sourceElement; + } + + public EList visibleMemberships(boolean isRecursive, boolean includeAll, boolean includeProtectedInherited) { + if (this.sourceElement instanceof Namespace namespace) { + return this.visibleMemberships(namespace, isRecursive, includeAll, includeProtectedInherited); + } else { + return new BasicEList<>(); + } + } + + private EList visibleMemberships(Namespace self, boolean isRecursive, boolean includeAll, boolean includeProtectedInherited) { + if (this.visited.contains(self)) { + return new BasicEList<>(); + } + + // Protected against infinite loop while iterating on imported/inherited elements + this.visited.add(self); + + NameConflictingFilter nameConflictingFilter = new NameConflictingFilter(); + List directMemberships = self.getOwnedMembership().stream() + .filter(m -> includeAll || m.getVisibility() == VisibilityKind.PUBLIC) + .filter(nameConflictingFilter) + .collect(toList()); + + self.getOwnedImport().stream() + .filter(m -> includeAll || m.getVisibility() == VisibilityKind.PUBLIC) + .flatMap(imp -> this.importedMemberships(imp).stream()) + .filter(nameConflictingFilter) + .forEach(directMemberships::add); + + if (self instanceof Type type) { + + this.inheritedMemberships(type).stream() + .filter(rel -> includeAll || (includeProtectedInherited && rel.getVisibility() == VisibilityKind.PROTECTED) || rel.getVisibility() == VisibilityKind.PUBLIC) + .filter(nameConflictingFilter) + .forEach(directMemberships::add); + + } + + BasicEList visibleMemberships = new BasicEList<>(directMemberships); + + if (isRecursive) { + List recursiveMembers = new BasicEList<>(); + for (Membership m : visibleMemberships) { + if (m.getMemberElement() instanceof Namespace subNamespace) { + if (!visibleMemberships.contains(subNamespace)) { + recursiveMembers.addAll(this.visibleMemberships(subNamespace, isRecursive, includeAll, includeProtectedInherited)); + } + } + } + visibleMemberships.addAll(recursiveMembers); + } + + return visibleMemberships; + } + + public EList inheritedMemberships() { + if (this.sourceElement instanceof Type type) { + return this.inheritedMemberships(type); + } else { + return new BasicEList<>(); + } + } + + private EList inheritedMemberships(Type self) { + this.visited.add(self); + + NameConflictingFilter namefilter = new NameConflictingFilter(); + namefilter.fillUsedNames(self.getOwnedMembership()); + Conjugation conjugator = self.getOwnedConjugator(); + List conjugatedMemberships = List.of(); + if (conjugator != null) { + Type type = conjugator.getOriginalType(); + if (type != null) { + conjugatedMemberships = this.visibleMemberships(type, false, true, true).stream().filter(namefilter).toList(); + } + } + + List generalMemberships = new BasicEList<>(); + for (Specialization specialization : self.getOwnedSpecialization()) { + Type general = specialization.getGeneral(); + if (general != null && !this.visited.contains(general)) { + this.visibleMemberships(general, false, true, true).stream() + .filter(namefilter) + .forEach(generalMemberships::add); + } + } + + Membership[] data = Stream.concat(conjugatedMemberships.stream(), generalMemberships.stream()) + // Also inherit protected memberships + .filter(rel -> rel.getVisibility() != VisibilityKind.PRIVATE) + .toArray(Membership[]::new); + return new EcoreEList.UnmodifiableEList<>((InternalEObject) self, SysmlPackage.eINSTANCE.getType_InheritedMembership(), data.length, data); + } + + public EList importedMemberships() { + if (this.sourceElement instanceof Import imp) { + return this.importedMemberships(imp); + } else { + return new BasicEList<>(); + } + } + + private EList importedMemberships(Import self) { + EList importedMemberships = new BasicEList<>(); + if (self instanceof NamespaceImport nmImport) { + importedMemberships = this.importedMemberships(nmImport); + } else if (self instanceof MembershipImport msImport) { + importedMemberships = this.importedMemberships(msImport); + } + return importedMemberships; + } + + private EList importedMemberships(MembershipImport msImport) { + BasicEList importedMemberships = new BasicEList<>(); + Membership membership = msImport.getImportedMembership(); + if (membership != null) { + Element member = membership.getMemberElement(); + if (member != null) { + if (!msImport.isIsRecursive() || !(member instanceof Namespace)) { + importedMemberships.add(membership); + } else if (member instanceof Namespace namespace) { + if (!this.visited.contains(namespace)) { + importedMemberships.add(membership); + importedMemberships.addAll(this.visibleMemberships(namespace, msImport.isIsRecursive(), msImport.isIsImportAll(), false)); + } + } + } + } + return importedMemberships; + } + + private EList importedMemberships(NamespaceImport self) { + Namespace aImportedNamespace = self.getImportedNamespace(); + BasicEList result = new BasicEList<>(); + if (aImportedNamespace != null && !this.visited.contains(aImportedNamespace)) { + result.addAll(this.visibleMemberships(aImportedNamespace, self.isIsRecursive(), self.isIsImportAll(), false)); + } + return result; + } +} diff --git a/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/NameConflictingFilter.java b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/NameConflictingFilter.java new file mode 100644 index 000000000..88d4f23b4 --- /dev/null +++ b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/NameConflictingFilter.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2024, 2026 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.syson.sysml.metamodel.helper; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Predicate; + +import org.eclipse.syson.sysml.Element; +import org.eclipse.syson.sysml.Membership; + +/** + * Filter in charge of checking if element has a conflicting name or short name with a set a previously checked + * elements. + * + *

+ * This filter only checks for elements that has at least an {@link Element#effectiveName()} or an + * {@link Element#effectiveShortName()}. If an element has neither, it matches the given element since it can not create + * any name conflict. + *

+ * + * @author Arthur Daussy + */ +public class NameConflictingFilter implements Predicate { + + private final Set usedNames = new HashSet<>(); + + @Override + public boolean test(Membership member) { + boolean test = true; + if (member != null) { + if (member.getMemberName() != null + && member.getMemberElement() != null + && member.getMemberName() != member.getMemberElement().getName()) { + test = this.checkConflictingNames(member.getMemberName()); + } else { + Element memberElement = member.getMemberElement(); + if (memberElement != null) { + test = this.checkConflictingElement(memberElement); + } + } + } + + return test; + } + + public boolean checkConflictingElement(Element memberElement) { + return this.checkConflictingNames(memberElement.effectiveName()) && this.checkConflictingNames(memberElement.effectiveShortName()); + } + + public boolean checkConflictingNames(String name) { + + boolean hasName = name != null; + if (hasName) { + boolean hasConflictingName = hasName && this.usedNames.contains(name); + + boolean noConflict = !hasConflictingName; + if (noConflict) { + // Only add to forbidden names if the element is not conflicting on both the shortname and the + // name + this.usedNames.add(name); + } + return noConflict; + } // Else if the element has neither a name or a short name it can not create name conflict + return true; + } + + public void fillUsedNames(List existingMembers) { + for (Membership member : existingMembers) { + Element memberElement = member.getMemberElement(); + if (memberElement != null) { + String name = memberElement.effectiveName(); + String shortName = memberElement.effectiveShortName(); + if (name != null) { + this.usedNames.add(name); + } + if (shortName != null) { + this.usedNames.add(shortName); + } + } + } + } + +} diff --git a/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/NameHelper.java b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/NameHelper.java new file mode 100644 index 000000000..7e933c21a --- /dev/null +++ b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/helper/NameHelper.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2024, 2026 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.syson.sysml.metamodel.helper; + +import java.util.Arrays; +import java.util.List; +import java.util.regex.Pattern; + +import org.apache.commons.text.StringEscapeUtils; +import org.eclipse.syson.sysml.metamodel.services.textual.SysMLv2Keywords; + +/** + * Set of methods to help to manipulate/escape name/qualified name of sysml elements. + * + * @author Guillaume Escande + */ +public final class NameHelper { + + private static final java.util.regex.Pattern VALID_CHARS = Pattern.compile("[^a-zA-Z0-9_]"); + + /** + * Parse a qualified name to extract list of sections. + * + * @param qualifiedName + * qualified name to split + * @return + */ + public List parseQualifiedName(String qualifiedName) { + return Arrays.asList(qualifiedName.split("::")); + } + + /** + * Escape a string. + * + * @param str + * string to escape + * @return + */ + public String escapeString(String str) { + return StringEscapeUtils.escapeJava(str); + } + + /** + * Unescape a string. + * + * @param str + * string to unescape + * @return + */ + public String unescapeString(String str) { + if (str != null && str.length() > 1 && str.startsWith("'") && str.endsWith("'")) { + return str.substring(1, str.length() - 1); + } + return str; + } + + /** + * Set a String printable for SysMLv2 name. + * + * @param initialName + * string to set printable + * @return a String printable for SysMLv2 name + */ + public String toPrintableName(String initialName) { + return this.toPrintableName(initialName, false); + } + + /** + * Set a String printable for SysMLv2 name. + * + * @param initialName + * string to set printable + * @param escapeSingleQuotes + * whether the single quotes should be escaped or not inside the printable value + * @return a String printable for SysMLv2 name + */ + public String toPrintableName(String initialName, boolean escapeSingleQuotes) { + String name; + if (initialName == null || initialName.isEmpty()) { + name = ""; + } else if (VALID_CHARS.matcher(initialName).find() || !this.isLetterOrUnderscore(initialName.charAt(0)) || SysMLv2Keywords.KEYWORDS.contains(initialName.trim())) { + if (escapeSingleQuotes) { + name = '\'' + initialName.replaceAll("'", "\\\\'") + '\''; + } else { + name = '\'' + initialName + '\''; + } + } else { + name = initialName; + } + return name; + } + + private boolean isLetterOrUnderscore(char c) { + return c == '_' || this.isLowerCaseLetter(c) || this.isUpperCaseLetter(c); + } + + private boolean isUpperCaseLetter(char c) { + return c >= 'a' && c <= 'z'; + } + + private boolean isLowerCaseLetter(char c) { + return c >= 'A' && c <= 'Z'; + } + +} diff --git a/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/ElementInitializerSwitch.java b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/ElementInitializerSwitch.java index eae84c54a..6fcc283c3 100644 --- a/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/ElementInitializerSwitch.java +++ b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/ElementInitializerSwitch.java @@ -61,7 +61,7 @@ import org.eclipse.syson.sysml.ViewDefinition; import org.eclipse.syson.sysml.ViewUsage; import org.eclipse.syson.sysml.VisibilityKind; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.eclipse.syson.sysml.util.SysmlSwitch; /** diff --git a/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/FeatureChainComputer.java b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/FeatureChainComputer.java index ff5801cbe..2d6d46a2f 100644 --- a/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/FeatureChainComputer.java +++ b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/FeatureChainComputer.java @@ -29,7 +29,7 @@ import org.eclipse.syson.sysml.Specialization; import org.eclipse.syson.sysml.SysmlPackage; import org.eclipse.syson.sysml.Type; -import org.eclipse.syson.sysml.helper.EMFUtils; +import org.eclipse.syson.sysml.metamodel.helper.EMFUtils; /** * Object in charge of computing a chain of feature to access a {@link Feature} from one {@link Element}. diff --git a/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/SysMLElementSerializer.java b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/SysMLElementSerializer.java similarity index 94% rename from backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/SysMLElementSerializer.java rename to backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/SysMLElementSerializer.java index 3100c7ce5..a625cd3c2 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/SysMLElementSerializer.java +++ b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/SysMLElementSerializer.java @@ -10,15 +10,10 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.textual; +package org.eclipse.syson.sysml.metamodel.services.textual; import static java.util.stream.Collectors.joining; -import static org.eclipse.syson.sysml.textual.utils.SysMLRelationPredicates.IS_DEFINITION_BODY_ITEM_MEMBER; -import static org.eclipse.syson.sysml.textual.utils.SysMLRelationPredicates.IS_IMPORT; -import static org.eclipse.syson.sysml.textual.utils.SysMLRelationPredicates.IS_MEMBERSHIP; -import static org.eclipse.syson.sysml.textual.utils.SysMLRelationPredicates.IS_METADATA_USAGE; -import java.lang.Class; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; @@ -36,15 +31,134 @@ import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.InternalEObject; -import org.eclipse.syson.sysml.*; +import org.eclipse.syson.sysml.AcceptActionUsage; +import org.eclipse.syson.sysml.ActionDefinition; +import org.eclipse.syson.sysml.ActionUsage; +import org.eclipse.syson.sysml.ActorMembership; +import org.eclipse.syson.sysml.AllocationDefinition; +import org.eclipse.syson.sysml.AllocationUsage; +import org.eclipse.syson.sysml.AnalysisCaseUsage; +import org.eclipse.syson.sysml.AssertConstraintUsage; +import org.eclipse.syson.sysml.AssignmentActionUsage; +import org.eclipse.syson.sysml.AttributeDefinition; +import org.eclipse.syson.sysml.AttributeUsage; +import org.eclipse.syson.sysml.CalculationDefinition; +import org.eclipse.syson.sysml.Classifier; +import org.eclipse.syson.sysml.CollectExpression; +import org.eclipse.syson.sysml.Comment; +import org.eclipse.syson.sysml.ConjugatedPortDefinition; +import org.eclipse.syson.sysml.ConjugatedPortTyping; +import org.eclipse.syson.sysml.ConnectionUsage; +import org.eclipse.syson.sysml.Connector; +import org.eclipse.syson.sysml.ConstraintUsage; +import org.eclipse.syson.sysml.ControlNode; +import org.eclipse.syson.sysml.DecisionNode; +import org.eclipse.syson.sysml.Definition; +import org.eclipse.syson.sysml.Documentation; +import org.eclipse.syson.sysml.Element; +import org.eclipse.syson.sysml.EndFeatureMembership; +import org.eclipse.syson.sysml.EnumerationDefinition; +import org.eclipse.syson.sysml.EnumerationUsage; +import org.eclipse.syson.sysml.EventOccurrenceUsage; +import org.eclipse.syson.sysml.ExhibitStateUsage; +import org.eclipse.syson.sysml.Expose; +import org.eclipse.syson.sysml.Expression; +import org.eclipse.syson.sysml.Feature; +import org.eclipse.syson.sysml.FeatureChainExpression; +import org.eclipse.syson.sysml.FeatureChaining; +import org.eclipse.syson.sysml.FeatureDirectionKind; +import org.eclipse.syson.sysml.FeatureMembership; +import org.eclipse.syson.sysml.FeatureReferenceExpression; +import org.eclipse.syson.sysml.FeatureTyping; +import org.eclipse.syson.sysml.FeatureValue; +import org.eclipse.syson.sysml.FlowEnd; +import org.eclipse.syson.sysml.FlowUsage; +import org.eclipse.syson.sysml.ForkNode; +import org.eclipse.syson.sysml.Import; +import org.eclipse.syson.sysml.IncludeUseCaseUsage; +import org.eclipse.syson.sysml.InterfaceDefinition; +import org.eclipse.syson.sysml.InvocationExpression; +import org.eclipse.syson.sysml.ItemDefinition; +import org.eclipse.syson.sysml.ItemUsage; +import org.eclipse.syson.sysml.JoinNode; +import org.eclipse.syson.sysml.LibraryPackage; +import org.eclipse.syson.sysml.LiteralBoolean; +import org.eclipse.syson.sysml.LiteralExpression; +import org.eclipse.syson.sysml.LiteralInfinity; +import org.eclipse.syson.sysml.LiteralInteger; +import org.eclipse.syson.sysml.LiteralRational; +import org.eclipse.syson.sysml.LiteralString; +import org.eclipse.syson.sysml.Membership; +import org.eclipse.syson.sysml.MembershipExpose; +import org.eclipse.syson.sysml.MembershipImport; +import org.eclipse.syson.sysml.MergeNode; +import org.eclipse.syson.sysml.Metaclass; +import org.eclipse.syson.sysml.MetadataAccessExpression; +import org.eclipse.syson.sysml.MetadataDefinition; +import org.eclipse.syson.sysml.MetadataUsage; +import org.eclipse.syson.sysml.MultiplicityRange; +import org.eclipse.syson.sysml.Namespace; +import org.eclipse.syson.sysml.NamespaceExpose; +import org.eclipse.syson.sysml.NamespaceImport; +import org.eclipse.syson.sysml.NullExpression; +import org.eclipse.syson.sysml.ObjectiveMembership; +import org.eclipse.syson.sysml.OccurrenceDefinition; +import org.eclipse.syson.sysml.OccurrenceUsage; +import org.eclipse.syson.sysml.OperatorExpression; +import org.eclipse.syson.sysml.OwningMembership; import org.eclipse.syson.sysml.Package; -import org.eclipse.syson.sysml.helper.EMFUtils; -import org.eclipse.syson.sysml.helper.LabelConstants; -import org.eclipse.syson.sysml.textual.utils.Appender; -import org.eclipse.syson.sysml.textual.utils.INameDeresolver; -import org.eclipse.syson.sysml.textual.utils.Status; -import org.eclipse.syson.sysml.textual.utils.SysMLKeywordSwitch; -import org.eclipse.syson.sysml.textual.utils.SysMLRelationPredicates; +import org.eclipse.syson.sysml.ParameterMembership; +import org.eclipse.syson.sysml.PartDefinition; +import org.eclipse.syson.sysml.PartUsage; +import org.eclipse.syson.sysml.PayloadFeature; +import org.eclipse.syson.sysml.PerformActionUsage; +import org.eclipse.syson.sysml.PortDefinition; +import org.eclipse.syson.sysml.PortUsage; +import org.eclipse.syson.sysml.PortionKind; +import org.eclipse.syson.sysml.Redefinition; +import org.eclipse.syson.sysml.ReferenceSubsetting; +import org.eclipse.syson.sysml.ReferenceUsage; +import org.eclipse.syson.sysml.Relationship; +import org.eclipse.syson.sysml.RenderingUsage; +import org.eclipse.syson.sysml.RequirementConstraintMembership; +import org.eclipse.syson.sysml.RequirementDefinition; +import org.eclipse.syson.sysml.RequirementUsage; +import org.eclipse.syson.sysml.ReturnParameterMembership; +import org.eclipse.syson.sysml.SatisfyRequirementUsage; +import org.eclipse.syson.sysml.SelectExpression; +import org.eclipse.syson.sysml.SendActionUsage; +import org.eclipse.syson.sysml.Specialization; +import org.eclipse.syson.sysml.StakeholderMembership; +import org.eclipse.syson.sysml.StateDefinition; +import org.eclipse.syson.sysml.StateSubactionMembership; +import org.eclipse.syson.sysml.StateUsage; +import org.eclipse.syson.sysml.Subclassification; +import org.eclipse.syson.sysml.SubjectMembership; +import org.eclipse.syson.sysml.Subsetting; +import org.eclipse.syson.sysml.Succession; +import org.eclipse.syson.sysml.SuccessionAsUsage; +import org.eclipse.syson.sysml.SysmlPackage; +import org.eclipse.syson.sysml.TextualRepresentation; +import org.eclipse.syson.sysml.TransitionFeatureKind; +import org.eclipse.syson.sysml.TransitionFeatureMembership; +import org.eclipse.syson.sysml.TransitionUsage; +import org.eclipse.syson.sysml.TriggerInvocationExpression; +import org.eclipse.syson.sysml.TriggerKind; +import org.eclipse.syson.sysml.Type; +import org.eclipse.syson.sysml.Usage; +import org.eclipse.syson.sysml.UseCaseDefinition; +import org.eclipse.syson.sysml.UseCaseUsage; +import org.eclipse.syson.sysml.VerificationCaseUsage; +import org.eclipse.syson.sysml.ViewUsage; +import org.eclipse.syson.sysml.ViewpointDefinition; +import org.eclipse.syson.sysml.VisibilityKind; +import org.eclipse.syson.sysml.metamodel.helper.EMFUtils; +import org.eclipse.syson.sysml.metamodel.helper.LabelConstants; +import org.eclipse.syson.sysml.metamodel.services.textual.utils.Appender; +import org.eclipse.syson.sysml.metamodel.services.textual.utils.INameDeresolver; +import org.eclipse.syson.sysml.metamodel.services.textual.utils.Status; +import org.eclipse.syson.sysml.metamodel.services.textual.utils.SysMLKeywordSwitch; +import org.eclipse.syson.sysml.metamodel.services.textual.utils.SysMLRelationPredicates; import org.eclipse.syson.sysml.util.SysmlSwitch; /** @@ -64,6 +178,8 @@ public class SysMLElementSerializer extends SysmlSwitch { private final SysMLKeywordSwitch keywordProvider = new SysMLKeywordSwitch(); + private final SysMLRelationPredicates relationPredicates = new SysMLRelationPredicates(); + private final Consumer reportConsumer; private final boolean needEscapeCharacter; @@ -294,7 +410,10 @@ public String caseConnectionUsage(ConnectionUsage connectionUsage) { List ends = this.appendConnectorPart(connectorPartBuilder, connectionUsage); - List contentMemberships = connectionUsage.getOwnedMembership().stream().filter(IS_DEFINITION_BODY_ITEM_MEMBER).filter(e -> !ends.contains(e)).toList(); + List contentMemberships = connectionUsage.getOwnedMembership().stream() + .filter(this.relationPredicates.isDefinitionBodyItemMember()) + .filter(e -> !ends.contains(e)) + .toList(); if (!declarationAndValueBuilder.isEmpty() || !contentMemberships.isEmpty()) { // If the ConnectionUsage as a declaration, a value or some content we need to use the keyword connection @@ -570,7 +689,9 @@ public String caseLibraryPackage(LibraryPackage libraryPackage) { } builder.append("library package "); this.appendNameWithShortName(builder, libraryPackage); - List children = libraryPackage.getOwnedRelationship().stream().filter(IS_MEMBERSHIP.and(IS_METADATA_USAGE.negate()).or(IS_IMPORT)).toList(); + List children = libraryPackage.getOwnedRelationship().stream() + .filter(this.relationPredicates.isMembership().and(this.relationPredicates.isMetadataUsage().negate()).or(this.relationPredicates.isImport())) + .toList(); this.appendChildrenContent(builder, libraryPackage, children); return builder.toString(); } @@ -811,7 +932,9 @@ public String casePackage(Package pack) { Appender builder = this.newAppender(); builder.append("package "); this.appendNameWithShortName(builder, pack); - List children = pack.getOwnedRelationship().stream().filter(IS_MEMBERSHIP.and(IS_METADATA_USAGE.negate()).or(IS_IMPORT)).toList(); + List children = pack.getOwnedRelationship().stream() + .filter(this.relationPredicates.isMembership().and(this.relationPredicates.isMetadataUsage().negate()).or(this.relationPredicates.isImport())) + .toList(); this.appendChildrenContent(builder, pack, children); return builder.toString(); } @@ -1202,7 +1325,7 @@ public String caseSuccessionAsUsage(SuccessionAsUsage successionAsUsage) { } List children = successionAsUsage.getOwnedRelationship().stream() - .filter(IS_DEFINITION_BODY_ITEM_MEMBER) + .filter(this.relationPredicates.isDefinitionBodyItemMember()) .toList(); this.appendChildrenContent(builder, successionAsUsage, children); @@ -1231,15 +1354,7 @@ public String caseTextualRepresentation(TextualRepresentation textualRepresentat @Override public String caseTransitionFeatureMembership(TransitionFeatureMembership transitionFeatureMembership) { - var builder = this.newAppender(); - // Weird code.... - if (transitionFeatureMembership.getKind() == TransitionFeatureKind.GUARD) { - List expressions = transitionFeatureMembership.getOwnedRelatedElement().stream() - .filter(Expression.class::isInstance) - .map(Expression.class::cast) - .map(this::doSwitch) - .toList(); - } else { + if (transitionFeatureMembership.getKind() != TransitionFeatureKind.GUARD) { this.reportConsumer.accept(Status.warning("TransitionFeatureMembership of kind {0} are not yet handled", transitionFeatureMembership.getKind())); } return super.caseTransitionFeatureMembership(transitionFeatureMembership); @@ -1299,7 +1414,8 @@ public String caseTransitionUsage(TransitionUsage transitionUsage) { } // Append usage body (removed already handled element : Succession and guard - List children = transitionUsage.getOwnedRelationship().stream().filter(IS_DEFINITION_BODY_ITEM_MEMBER) + List children = transitionUsage.getOwnedRelationship().stream() + .filter(this.relationPredicates.isDefinitionBodyItemMember()) .filter(e -> !(e instanceof ParameterMembership)) .toList(); this.appendChildrenContent(builder, transitionUsage, children); @@ -1594,7 +1710,9 @@ private String serializeDeclarationWithModifiers(Appender builder, Usage usage, } private void appendDefinitionBody(Appender builder, Usage usage) { - List children = usage.getOwnedRelationship().stream().filter(IS_DEFINITION_BODY_ITEM_MEMBER).toList(); + List children = usage.getOwnedRelationship().stream() + .filter(this.relationPredicates.isDefinitionBodyItemMember()) + .toList(); this.appendChildrenContent(builder, usage, children); } @@ -2394,7 +2512,7 @@ private void appendAnnotatedElements(Appender builder, Comment comment, EListnull if no direct container of the expected type */ - private T getDirectContainer(EObject element, Class expected) { + private T getDirectContainer(EObject element, java.lang.Class expected) { EObject eContainer = element.eContainer(); T result = null; if (expected.isInstance(eContainer)) { @@ -2439,7 +2557,7 @@ private void appendControlNodePrefix(Appender builder, ControlNode controlNode) private void appendActionNodeBody(Appender appender, ControlNode controlNode) { this.appendChildrenContent(appender, controlNode, controlNode.getOwnedRelationship().stream() - .filter(SysMLRelationPredicates.IS_ANNOTATING_ELEMENT) + .filter(this.relationPredicates.isAnnotatingElement()) .toList()); } @@ -2483,7 +2601,7 @@ private void appendDecisionTransition(TransitionUsage transitionUsage, Appender // Append usage body (removed already handled element : Succession and guard List children = transitionUsage.getOwnedRelationship().stream() - .filter(IS_DEFINITION_BODY_ITEM_MEMBER) + .filter(this.relationPredicates.isDefinitionBodyItemMember()) .filter(e -> !alreadyHandledElements.contains(e) && !(e instanceof ParameterMembership)) .toList(); this.appendChildrenContent(builder, transitionUsage, children); @@ -2500,7 +2618,9 @@ private String getDefinitionKeyword(Definition def) { private void appendDefinition(Appender builder, Definition definition) { this.appendDefinitionDeclaration(builder, definition); - List children = definition.getOwnedRelationship().stream().filter(IS_DEFINITION_BODY_ITEM_MEMBER).toList(); + List children = definition.getOwnedRelationship().stream() + .filter(this.relationPredicates.isDefinitionBodyItemMember()) + .toList(); this.appendChildrenContent(builder, definition, children); } diff --git a/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/SysMLSerializingOptions.java b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/SysMLSerializingOptions.java similarity index 95% rename from backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/SysMLSerializingOptions.java rename to backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/SysMLSerializingOptions.java index 28f8fc40f..cb83429c9 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/SysMLSerializingOptions.java +++ b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/SysMLSerializingOptions.java @@ -10,11 +10,11 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.textual; +package org.eclipse.syson.sysml.metamodel.services.textual; import java.util.Objects; -import org.eclipse.syson.sysml.textual.utils.INameDeresolver; +import org.eclipse.syson.sysml.metamodel.services.textual.utils.INameDeresolver; /** * Option used in the SysmlSerializer. diff --git a/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/SysMLv2Keywords.java b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/SysMLv2Keywords.java new file mode 100644 index 000000000..8d740ba34 --- /dev/null +++ b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/SysMLv2Keywords.java @@ -0,0 +1,259 @@ +/******************************************************************************* + * Copyright (c) 2026 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.syson.sysml.metamodel.services.textual; + +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; + +/** + * Gather all keywords reserved by the SysML V2 textual language. + * + * @author Arthur Daussy + */ +public final class SysMLv2Keywords { + + // Symbols / Operators / Punctuation + public static final String LESS_THAN = "<"; + public static final String GREATER_THAN = ">"; + public static final String SEMICOLON = ";"; + + public static final String LEFT_BRACE = "{"; + public static final String RIGHT_BRACE = "}"; + + public static final String COMMA = ","; + public static final String DOT = "."; + + public static final String LEFT_PAREN = "("; + public static final String RIGHT_PAREN = ")"; + + public static final String LEFT_BRACKET = "["; + public static final String RIGHT_BRACKET = "]"; + + public static final String AT_SIGN = "@"; + public static final String HASH = "#"; + public static final String TILDE = "\u007E"; + + public static final String COLON = ":"; + public static final String DOUBLE_COLON = "::"; + + public static final String STAR = "*"; + public static final String DOUBLE_STAR = "**"; + + public static final String RANGE = ".."; + public static final String OPTIONAL_NAVIGATION = ".?"; + + public static final String ARROW = "->"; + public static final String IMPLIES = "=>"; + + public static final String EQUALS = "="; + public static final String ASSIGNMENT = ":="; + + // SysML/DSL-specific operators (based on your tokens) + public static final String SPECIALIZES_OPERATOR = ":>"; + public static final String REDEFINES_OPERATOR = ":>>"; + public static final String DOUBLE_COLON_SPECIALIZES = "::>"; + + // Word tokens / Keywords + public static final String DEPENDENCY = "dependency"; + public static final String FROM = "from"; + public static final String TO = "to"; + public static final String COMMENT = "comment"; + public static final String ABOUT = "about"; + public static final String LOCALE = "locale"; + public static final String DOC = "doc"; + public static final String REP = "rep"; + public static final String LANGUAGE = "language"; + public static final String METADATA = "metadata"; + public static final String DEF = "def"; + public static final String ABSTRACT = "abstract"; + public static final String REF = "ref"; + public static final String REDEFINES = "redefines"; + public static final String STANDARD = "standard"; + public static final String LIBRARY = "library"; + public static final String PACKAGE = "package"; + public static final String FILTER = "filter"; + public static final String ALIAS = "alias"; + public static final String FOR = "for"; + public static final String IMPORT = "import"; + public static final String ALL = "all"; + + public static final String PUBLIC = "public"; + public static final String PRIVATE = "private"; + public static final String PROTECTED = "protected"; + + public static final String SPECIALIZES = "specializes"; + public static final String ORDERED = "ordered"; + public static final String NONUNIQUE = "nonunique"; + public static final String DEFINED = "defined"; + public static final String BY = "by"; + public static final String SUBSETS = "subsets"; + public static final String REFERENCES = "references"; + public static final String CROSSES = "crosses"; + public static final String VARIATION = "variation"; + public static final String VARIANT = "variant"; + + public static final String IN = "in"; + public static final String OUT = "out"; + public static final String INOUT = "inout"; + + public static final String DERIVED = "derived"; + public static final String CONSTANT = "constant"; + public static final String END = "end"; + public static final String DEFAULT = "default"; + + public static final String ATTRIBUTE = "attribute"; + public static final String ENUM = "enum"; + + public static final String OCCURRENCE = "occurrence"; + public static final String INDIVIDUAL = "individual"; + public static final String SNAPSHOT = "snapshot"; + public static final String TIMESLICE = "timeslice"; + public static final String EVENT = "event"; + public static final String THEN = "then"; + public static final String ITEM = "item"; + public static final String PART = "part"; + public static final String PORT = "port"; + + public static final String BINDING = "binding"; + public static final String BIND = "bind"; + public static final String SUCCESSION = "succession"; + public static final String FIRST = "first"; + + public static final String CONNECTION = "connection"; + public static final String CONNECT = "connect"; + public static final String INTERFACE = "interface"; + + public static final String ALLOCATION = "allocation"; + public static final String ALLOCATE = "allocate"; + public static final String FLOW = "flow"; + public static final String MESSAGE = "message"; + public static final String OF = "of"; + + public static final String ACTION = "action"; + public static final String PERFORM = "perform"; + public static final String ACCEPT = "accept"; + public static final String VIA = "via"; + public static final String AT = "at"; + public static final String AFTER = "after"; + public static final String WHEN = "when"; + public static final String SEND = "send"; + public static final String ASSIGN = "assign"; + + public static final String IF = "if"; + public static final String ELSE = "else"; + public static final String WHILE = "while"; + public static final String LOOP = "loop"; + public static final String UNTIL = "until"; + public static final String TERMINATE = "terminate"; + public static final String MERGE = "merge"; + public static final String DECIDE = "decide"; + public static final String JOIN = "join"; + public static final String FORK = "fork"; + + public static final String STATE = "state"; + public static final String PARALLEL = "parallel"; + public static final String ENTRY = "entry"; + public static final String DO = "do"; + public static final String EXIT = "exit"; + public static final String EXHIBIT = "exhibit"; + public static final String TRANSITION = "transition"; + public static final String CALC = "calc"; + public static final String RETURN = "return"; + + public static final String CONSTRAINT = "constraint"; + public static final String ASSERT = "assert"; + public static final String NOT = "not"; + + public static final String REQUIREMENT = "requirement"; + public static final String SUBJECT = "subject"; + public static final String ASSUME = "assume"; + public static final String REQUIRE = "require"; + public static final String FRAME = "frame"; + + public static final String ACTOR = "actor"; + public static final String STAKEHOLDER = "stakeholder"; + public static final String SATISFY = "satisfy"; + public static final String CONCERN = "concern"; + public static final String CASE = "case"; + public static final String OBJECTIVE = "objective"; + public static final String ANALYSIS = "analysis"; + public static final String VERIFICATION = "verification"; + public static final String VERIFY = "verify"; + public static final String USE = "use"; + public static final String INCLUDE = "include"; + public static final String VIEW = "view"; + public static final String RENDER = "render"; + public static final String RENDERING = "rendering"; + public static final String EXPOSE = "expose"; + public static final String VIEWPOINT = "viewpoint"; + + /** All word-based DSL keywords. */ + public static final Set KEYWORDS; + + /** All operators / symbols / punctuation. */ + public static final Set OPERATORS; + + /** Union of KEYWORDS and OPERATORS. */ + public static final Set ALL_TOKENS; + + static { + KEYWORDS = Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList( + DEPENDENCY, FROM, TO, COMMENT, ABOUT, LOCALE, DOC, REP, LANGUAGE, METADATA, DEF, ABSTRACT, REF, + REDEFINES, STANDARD, LIBRARY, PACKAGE, FILTER, ALIAS, FOR, IMPORT, ALL, + PUBLIC, PRIVATE, PROTECTED, + SPECIALIZES, ORDERED, NONUNIQUE, DEFINED, BY, SUBSETS, REFERENCES, CROSSES, + VARIATION, VARIANT, + IN, OUT, INOUT, + DERIVED, CONSTANT, END, DEFAULT, + ATTRIBUTE, ENUM, + OCCURRENCE, INDIVIDUAL, SNAPSHOT, TIMESLICE, EVENT, THEN, ITEM, PART, PORT, + BINDING, BIND, SUCCESSION, FIRST, + CONNECTION, CONNECT, INTERFACE, + ALLOCATION, ALLOCATE, FLOW, MESSAGE, OF, + ACTION, PERFORM, ACCEPT, VIA, AT, AFTER, WHEN, SEND, ASSIGN, + IF, ELSE, WHILE, LOOP, UNTIL, TERMINATE, MERGE, DECIDE, JOIN, FORK, + STATE, PARALLEL, ENTRY, DO, EXIT, EXHIBIT, TRANSITION, CALC, RETURN, + CONSTRAINT, ASSERT, NOT, + REQUIREMENT, SUBJECT, ASSUME, REQUIRE, FRAME, + ACTOR, STAKEHOLDER, SATISFY, CONCERN, CASE, OBJECTIVE, ANALYSIS, + VERIFICATION, VERIFY, + USE, INCLUDE, VIEW, RENDER, RENDERING, EXPOSE, VIEWPOINT + ))); + + OPERATORS = Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList( + LESS_THAN, GREATER_THAN, SEMICOLON, + LEFT_BRACE, RIGHT_BRACE, + COMMA, DOT, + LEFT_PAREN, RIGHT_PAREN, + LEFT_BRACKET, RIGHT_BRACKET, + AT_SIGN, HASH, TILDE, + COLON, DOUBLE_COLON, + STAR, DOUBLE_STAR, + RANGE, OPTIONAL_NAVIGATION, + ARROW, IMPLIES, + EQUALS, ASSIGNMENT, + SPECIALIZES_OPERATOR, REDEFINES_OPERATOR, DOUBLE_COLON_SPECIALIZES + ))); + + LinkedHashSet all = new LinkedHashSet<>(KEYWORDS.size() + OPERATORS.size()); + all.addAll(KEYWORDS); + all.addAll(OPERATORS); + ALL_TOKENS = Collections.unmodifiableSet(all); + } + + private SysMLv2Keywords() { + // Utility class + } +} diff --git a/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/utils/Appender.java b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/utils/Appender.java similarity index 92% rename from backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/utils/Appender.java rename to backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/utils/Appender.java index 46c51e275..772cd8424 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/utils/Appender.java +++ b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/utils/Appender.java @@ -10,12 +10,12 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.textual.utils; +package org.eclipse.syson.sysml.metamodel.services.textual.utils; import java.util.Collection; import java.util.List; -import org.eclipse.syson.sysml.helper.NameHelper; +import org.eclipse.syson.sysml.metamodel.helper.NameHelper; /** * Object that concatenate string using some custom convention. @@ -33,7 +33,6 @@ public class Appender { private final Collection symbols = List.of('[', '(', '.', '@'); public Appender(String newLine, String indentation) { - super(); this.newLine = newLine; this.indentation = indentation; } @@ -42,12 +41,8 @@ public boolean isEmpty() { return this.builder.isEmpty() || this.builder.toString().trim().isBlank(); } - public static String toPrintableName(String initialName) { - return NameHelper.toPrintableName(initialName, true); - } - public Appender appendPrintableName(String name) { - this.append(toPrintableName(name)); + this.append(new NameHelper().toPrintableName(name, true)); return this; } diff --git a/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/utils/FileNameDeresolver.java b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/utils/FileNameDeresolver.java similarity index 94% rename from backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/utils/FileNameDeresolver.java rename to backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/utils/FileNameDeresolver.java index b02b4c88a..092b02147 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/utils/FileNameDeresolver.java +++ b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/utils/FileNameDeresolver.java @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.textual.utils; +package org.eclipse.syson.sysml.metamodel.services.textual.utils; import static java.util.stream.Collectors.toCollection; @@ -35,10 +35,10 @@ import org.eclipse.syson.sysml.Namespace; import org.eclipse.syson.sysml.SysmlPackage; import org.eclipse.syson.sysml.VisibilityKind; -import org.eclipse.syson.sysml.helper.DeresolvingNamespaceProvider; -import org.eclipse.syson.sysml.helper.EMFUtils; -import org.eclipse.syson.sysml.helper.MembershipComputer; -import org.eclipse.syson.sysml.helper.NameHelper; +import org.eclipse.syson.sysml.metamodel.helper.DeresolvingNamespaceProvider; +import org.eclipse.syson.sysml.metamodel.helper.EMFUtils; +import org.eclipse.syson.sysml.metamodel.helper.MembershipComputer; +import org.eclipse.syson.sysml.metamodel.helper.NameHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -90,7 +90,7 @@ public String getDeresolvedName(Element element, Element context) { for (Namespace deresolvingNamespace : deresolvingNamespaces) { // Check if resolving the direct identifier works (declaredShortName or declaredName) - String directIdentifier = getResolvableDirectIdentifier(element, deresolvingNamespace); + String directIdentifier = this.getResolvableDirectIdentifier(element, deresolvingNamespace); if (directIdentifier != null) { qualifiedNames.add(directIdentifier); } else { @@ -245,7 +245,7 @@ private String buildRelativeQualifiedName(Element element, Namespace owningNames * the namespace used to test the resolution of the identifier * @return an identifier or null if no direct resolvable identifier found. */ - private static String getResolvableDirectIdentifier(Element targetElement, Namespace contextNamespace) { + private String getResolvableDirectIdentifier(Element targetElement, Namespace contextNamespace) { String identifier = null; String shortName = targetElement.getDeclaredShortName(); if (shortName != null && !shortName.isBlank()) { @@ -266,7 +266,7 @@ private static String getResolvableDirectIdentifier(Element targetElement, Names } if (identifier != null) { - identifier = NameHelper.toPrintableName(identifier); + identifier = new NameHelper().toPrintableName(identifier); } return identifier; } @@ -301,9 +301,9 @@ private String getRelativeQualifiedName(String elementQn, Element element, Membe String importedElementQualifiedName = this.getQualifiedName(importedElement); if (importedElement != element && !importedElementQualifiedName.isEmpty()) { int partToRemove = importedElementQualifiedName.length() + 2; - qn = Appender.toPrintableName(importedElement.getName()) + "::" + elementQn.substring(partToRemove); + qn = new NameHelper().toPrintableName(importedElement.getName()) + "::" + elementQn.substring(partToRemove); } else { - qn = Appender.toPrintableName(element.getName()); + qn = new NameHelper().toPrintableName(element.getName()); } return qn; } diff --git a/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/utils/INameDeresolver.java b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/utils/INameDeresolver.java similarity index 77% rename from backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/utils/INameDeresolver.java rename to backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/utils/INameDeresolver.java index 686b3bf00..2576b2b30 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/utils/INameDeresolver.java +++ b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/utils/INameDeresolver.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2025 Obeo. + * Copyright (c) 2025, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -10,10 +10,15 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.textual.utils; +package org.eclipse.syson.sysml.metamodel.services.textual.utils; import org.eclipse.syson.sysml.Element; +/** + * Retrieve the name of the given element from a given context. + * + * @author arichard + */ public interface INameDeresolver { /** @@ -25,6 +30,6 @@ public interface INameDeresolver { * the context element from which the deresolution occurs * @return a name or null */ - public String getDeresolvedName(Element element, Element context); + String getDeresolvedName(Element element, Element context); } diff --git a/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/utils/Severity.java b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/utils/Severity.java similarity index 85% rename from backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/utils/Severity.java rename to backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/utils/Severity.java index e238c1e43..1bd09a9e0 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/utils/Severity.java +++ b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/utils/Severity.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024, 2025 Obeo. + * Copyright (c) 2024, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.textual.utils; +package org.eclipse.syson.sysml.metamodel.services.textual.utils; /** * Severity. diff --git a/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/utils/Status.java b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/utils/Status.java similarity index 96% rename from backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/utils/Status.java rename to backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/utils/Status.java index f08b36cb2..98e34967d 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/utils/Status.java +++ b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/utils/Status.java @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.textual.utils; +package org.eclipse.syson.sysml.metamodel.services.textual.utils; import java.text.MessageFormat; diff --git a/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/utils/SysMLKeywordSwitch.java b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/utils/SysMLKeywordSwitch.java similarity index 97% rename from backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/utils/SysMLKeywordSwitch.java rename to backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/utils/SysMLKeywordSwitch.java index 41376da5a..6f05bad32 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/textual/utils/SysMLKeywordSwitch.java +++ b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/utils/SysMLKeywordSwitch.java @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.textual.utils; +package org.eclipse.syson.sysml.metamodel.services.textual.utils; import org.eclipse.emf.ecore.EObject; @@ -42,7 +42,7 @@ import org.eclipse.syson.sysml.RequirementDefinition; import org.eclipse.syson.sysml.RequirementUsage; import org.eclipse.syson.sysml.SubjectMembership; -import org.eclipse.syson.sysml.textual.SysMLv2Keywords; +import org.eclipse.syson.sysml.metamodel.services.textual.SysMLv2Keywords; import org.eclipse.syson.sysml.util.SysmlSwitch; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/utils/SysMLRelationPredicates.java b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/utils/SysMLRelationPredicates.java new file mode 100644 index 000000000..e0191d175 --- /dev/null +++ b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/textual/utils/SysMLRelationPredicates.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright (c) 2024, 2026 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.syson.sysml.metamodel.services.textual.utils; + +import java.util.function.Predicate; +import java.util.stream.Stream; + +import org.eclipse.syson.sysml.AnnotatingElement; +import org.eclipse.syson.sysml.AttributeUsage; +import org.eclipse.syson.sysml.BindingConnectorAsUsage; +import org.eclipse.syson.sysml.Definition; +import org.eclipse.syson.sysml.Dependency; +import org.eclipse.syson.sysml.Element; +import org.eclipse.syson.sysml.EnumerationUsage; +import org.eclipse.syson.sysml.Import; +import org.eclipse.syson.sysml.Membership; +import org.eclipse.syson.sysml.MetadataFeature; +import org.eclipse.syson.sysml.MetadataUsage; +import org.eclipse.syson.sysml.OccurrenceUsage; +import org.eclipse.syson.sysml.OwningMembership; +import org.eclipse.syson.sysml.ReferenceUsage; +import org.eclipse.syson.sysml.Relationship; +import org.eclipse.syson.sysml.SuccessionAsUsage; +import org.eclipse.syson.sysml.SysmlPackage; +import org.eclipse.syson.sysml.VariantMembership; + +/** + * List of predicates to select Relationships. + * + * @author Arthur Daussy + */ +public class SysMLRelationPredicates { + + private final Predicate isNotUserDefineKeywordMember = r -> !this.isMemberElementA(r, MetadataUsage.class); + + private final Predicate isMembership = r -> r instanceof Membership; + + private final Predicate isImport = r -> r instanceof Import; + + private final Predicate isMetadataUsage = m -> this.isMemberElementA(m, MetadataUsage.class); + + private final Predicate isNonOccurrenceUsageMember = r -> this.isMemberElementA(r, Definition.class, ReferenceUsage.class, + AttributeUsage.class, EnumerationUsage.class, BindingConnectorAsUsage.class, SuccessionAsUsage.class) || this.isExtendedUsage(r); + + + // https://issues.omg.org/issues/KERML-307 + private final Predicate isAnnotatingElement = r -> this.isMemberElementA(r, AnnotatingElement.class) + && !this.isMemberElementA(r, MetadataFeature.class); + + private final Predicate isDefinitionMember = r -> this.isMemberElementA(r, Definition.class, Package.class) + || this.isAnnotatingElement.test(r) || this.isA(r, Dependency.class); + + private final Predicate isVariantUsageMember = r -> this.isA(r, VariantMembership.class); + + private final Predicate isStructureUsageElementMember = r -> this.isMemberElementA(r, OccurrenceUsage.class); + + private final Predicate isOccurrenceUsageMember = r -> this.isMemberElementA(r, OccurrenceUsage.class); + + private final Predicate isAliasMember = r -> r instanceof Membership membership && !(r instanceof OwningMembership) + && (membership.getMemberName() != null || membership.getShortName() != null); + + private final Predicate isDefinitionBodyItemMember = this.isNotUserDefineKeywordMember.and( + this.isDefinitionMember + .or(this.isVariantUsageMember) + .or(this.isNonOccurrenceUsageMember) + .or(this.isOccurrenceUsageMember) + .or(this.isAliasMember).or(this.isImport)); + + public Predicate isNotUserDefineKeywordMember() { + return this.isNotUserDefineKeywordMember; + } + + public Predicate isMembership() { + return this.isMembership; + } + + public Predicate isImport() { + return this.isImport; + } + + public Predicate isMetadataUsage() { + return this.isMetadataUsage; + } + + public Predicate isNonOccurrenceUsageMember() { + return this.isNonOccurrenceUsageMember; + } + + public Predicate isAnnotatingElement() { + return this.isAnnotatingElement; + } + + public Predicate isDefinitionMember() { + return this.isDefinitionMember; + } + + public Predicate isVariantUsageMember() { + return this.isVariantUsageMember; + } + + public Predicate isStructureUsageElementMember() { + return this.isStructureUsageElementMember; + } + + public Predicate isOccurrenceUsageMember() { + return this.isOccurrenceUsageMember; + } + + public Predicate isAliasMember() { + return this.isAliasMember; + } + + public Predicate isDefinitionBodyItemMember() { + return this.isDefinitionBodyItemMember; + } + + private boolean isMemberElementA(Relationship r, Class... types) { + if (r instanceof Membership membership) { + return this.isA(membership.getMemberElement(), types); + } + return false; + } + + private boolean isA(Element e, Class... types) { + if (e == null) { + return false; + } else { + return Stream.of(types).filter(t -> t.isInstance(e)).findAny().isPresent(); + } + } + + private boolean isExtendedUsage(Relationship r) { + return r instanceof Membership membership + && membership.getMemberElement() != null + && membership.getMemberElement().eClass() == SysmlPackage.eINSTANCE.getUsage(); + } +} diff --git a/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/util/ElementUtil.java b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/util/ElementUtil.java new file mode 100644 index 000000000..a25dc1d25 --- /dev/null +++ b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/util/ElementUtil.java @@ -0,0 +1,396 @@ +/******************************************************************************* + * Copyright (c) 2024, 2026 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.syson.sysml.metamodel.util; + +import com.fasterxml.uuid.Generators; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; + +import org.eclipse.emf.common.util.TreeIterator; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EAnnotation; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EcoreFactory; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.syson.sysml.Element; +import org.eclipse.syson.sysml.Import; +import org.eclipse.syson.sysml.LibraryPackage; +import org.eclipse.syson.sysml.Membership; +import org.eclipse.syson.sysml.Namespace; +import org.eclipse.syson.sysml.Specialization; +import org.eclipse.syson.sysml.SysmlPackage; +import org.eclipse.syson.sysml.TypeFeaturing; +import org.eclipse.syson.sysml.VisibilityKind; + +/** + * Util class for SysML elements. + * + * @author arichard + */ +public class ElementUtil { + + /** + * Scheme for URI locating standard KerML libraries. + */ + public static final String KERML_LIBRARY_SCHEME = "kermllibrary"; + + /** + * Scheme for URI locating standard SysML libraries. + */ + public static final String SYSML_LIBRARY_SCHEME = "sysmllibrary"; + + /** + * The UUID for NameSpace_URL as required in SysMLv2 specification. + */ + public static final UUID NAME_SPACE_URL_UUID = UUID.fromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8"); + + /** + * The prefix to prepend to all names for the construction of UUIDs as required in KerML specification. + */ + public static final String KERML_LIBRARY_BASE_URI = "https://www.omg.org/spec/KerML/"; + + /** + * The prefix to prepend to all names for the construction of UUIDs as required in SysMLv2 specification. + */ + public static final String SYSML_LIBRARY_BASE_URI = "https://www.omg.org/spec/SysML/"; + + /** + * The source of the {@link EAnnotation} used to flag imported {@link Resource}s. + */ + private static final String IMPORTED_EANNOTATION_SOURCE = "org.eclipse.syson.sysml.imported"; + + /** + * Checks if the given resource is one of KerML or SysML standard libraries. + * + * @param resource + * a {@link Resource} + * @return true is standard resource, false otherwise. + */ + public static boolean isStandardLibraryResource(Resource resource) { + if (resource != null && resource.getURI() != null) { + URI uri = resource.getURI(); + return uri.toString().startsWith(KERML_LIBRARY_SCHEME) || uri.toString().startsWith(SYSML_LIBRARY_SCHEME); + } + return false; + } + + /** + * Check if the given {@link Element} comes from a standard library (i.e. a {@link LibraryPackage} with its standard + * attribute set to true) or not. + * + * @param element + * the given {@link Element}. + * @return true if the given element is contained in a standard library, false otherwise. + */ + public static boolean isFromStandardLibrary(Element element) { + return element.libraryNamespace() instanceof LibraryPackage libraryPackage + && libraryPackage.isIsStandard(); + } + + /** + * Generate a UUID (a v5 for standard library elements a a random v4 random for others). + * + * @return a UUID. + */ + public static UUID generateUUID(Element element) { + UUID uuid = UUID.randomUUID(); + if (element instanceof LibraryPackage libraryPackage && libraryPackage.isIsStandard()) { + Resource resource = element.eResource(); + if (resource != null) { + String uri = ElementUtil.SYSML_LIBRARY_BASE_URI; + if (resource.getURI().toString().startsWith("kermllibrary:")) { + uri = ElementUtil.KERML_LIBRARY_BASE_URI; + } + String qualifiedName = element.getQualifiedName(); + if (qualifiedName != null) { + uuid = generateUUIDv5(ElementUtil.NAME_SPACE_URL_UUID, uri + qualifiedName); + } + } + } else if (isFromStandardLibrary(element) && element.getDeclaredName() != null && !noNeedForUUID(element)) { + String qualifiedName = element.getQualifiedName(); + Namespace libraryNamespace = element.libraryNamespace(); + if (qualifiedName != null && libraryNamespace != null) { + UUID namespaceUUID = UUID.fromString(libraryNamespace.getElementId()); + uuid = ElementUtil.generateUUIDv5(namespaceUUID, qualifiedName); + } + } + return uuid; + } + + private static boolean noNeedForUUID(Element element) { + return element instanceof Import || element instanceof Membership || element instanceof Specialization || element instanceof TypeFeaturing; + } + + /** + * Generate a UUID v5 from a given namespace and a value. + * + * @param namespaceUUID + * the namespace to use to generate the UUID. + * @param value + * the value (i.e. the qualified name of a SysML element) for which we want to generate the UUID. + * @return a UUID in version 5. + */ + public static UUID generateUUIDv5(UUID namespaceUUID, String value) { + return Generators.nameBasedGenerator(namespaceUUID, null).generate(value); + } + + /** + * Sets the provided {@code resource} with the provided {@code isImported} flag. + *

+ * An imported {@link Resource} returns {@code true} when calling {@code ElementUtil.isImported(resource)}. + *

+ * + * @param resource + * the {@link Resource} to set as imported + * @param isImported + * the imported flag to set + */ + public static void setIsImported(Resource resource, boolean isImported) { + resource.getContents().forEach(eObject -> { + if (eObject instanceof Element element) { + if (isImported) { + if (element.getEAnnotation(IMPORTED_EANNOTATION_SOURCE) == null) { + EAnnotation importedEAnnotation = EcoreFactory.eINSTANCE.createEAnnotation(); + importedEAnnotation.setSource(IMPORTED_EANNOTATION_SOURCE); + element.getEAnnotations().add(importedEAnnotation); + } + } else { + if (element.getEAnnotation(IMPORTED_EANNOTATION_SOURCE) != null) { + EcoreUtil.remove(element.getEAnnotation(IMPORTED_EANNOTATION_SOURCE)); + } + } + } + }); + } + + /** + * Returns {@code true} if the provided {@code resource} is imported. + * + * @param resource + * the {@link Resource} to check + * @return {@code true} if the provided {@code resource} is imported + */ + public static boolean isImported(Resource resource) { + return resource.getContents().stream() + .anyMatch(eObject -> eObject instanceof Element element && element.getEAnnotation(IMPORTED_EANNOTATION_SOURCE) != null); + } + + /** + * Find an {@link Element} that match the given name and type in the ResourceSet of the given element. + * + * @param object + * the object for which to find a corresponding type. + * @param elementName + * the element name to match. + * @param elementType + * the type to match. + * @return the found element or null. + */ + public T findByNameAndType(EObject object, String elementName, Class elementType) { + final T result = this.findByNameAndType(this.getAllRootsInResourceSet(object), elementName, elementType); + return result; + } + + /** + * Iterate over the given {@link Collection} of root elements to find a element with the given name and type. + * + * @param roots + * the elements to inspect. + * @param elementName + * the name to match. + * @param elementType + * the type to match. + * @return the found element or null. + */ + public T findByNameAndType(Collection roots, String elementName, Class elementType) { + String[] splitElementName = elementName.split("::"); + List qualifiedName = Arrays.asList(splitElementName); + for (final EObject root : roots) { + final T result; + if (qualifiedName.size() > 1) { + result = this.findInRootByQualifiedNameAndTypeFrom(root, qualifiedName, elementType); + } else { + result = this.findByNameAndTypeFrom(root, elementName, elementType); + } + if (result != null) { + return result; + } + } + return null; + } + + /** + * Count the number of existing ViewUsages inside the given Namespace. + * + * @param namespace + * the given {@link Namespace}. + * @return the number of existing ViewUsages inside the given Namespace. + */ + public long existingViewUsagesCountForRepresentationCreation(Namespace namespace) { + return namespace.getOwnedMember().stream() + .filter(member -> SysmlPackage.eINSTANCE.getViewUsage().equals(member.eClass())) + .count(); + } + + /** + * Iterate over the children of the given root {@link EObject} to find an {@link Element} with the given qualified + * name and type. + * + * @param root + * the root object to iterate. + * @param qualifiedName + * the qualified name to match. + * @param elementType + * the type to match. + * @return the found element or null. + */ + private T findInRootByQualifiedNameAndTypeFrom(EObject root, List qualifiedName, Class elementType) { + T element = null; + if (root instanceof Namespace namespace && namespace.eContainer() == null && namespace.getName() == null) { + // Ignore top-level namespaces with no name, they aren't part of the qualified name + element = this.findByQualifiedNameAndTypeFrom(namespace, qualifiedName, elementType); + } else if (root instanceof Element rootElt && this.nameMatches(rootElt, qualifiedName.get(0))) { + element = this.findByQualifiedNameAndTypeFrom(rootElt, qualifiedName.subList(1, qualifiedName.size()), elementType); + } + return element; + } + + /** + * Iterate over the children of the given parent {@link EObject} to find an {@link Element} with the given qualified + * name and type. + * + * @param parent + * the parent object to iterate. + * @param qualifiedName + * the qualified name to match. + * @param elementType + * the type to match. + * @return the found element or null. + */ + private T findByQualifiedNameAndTypeFrom(Element parent, List qualifiedName, Class elementType) { + T element = null; + + Optional child = parent.getOwnedElement().stream() + .filter(Element.class::isInstance) + .map(Element.class::cast) + .filter(elt -> this.nameMatches(elt, qualifiedName.get(0))) + .findFirst(); + if (child.isEmpty() && parent instanceof Namespace parentNamespace) { + // If the element is not owned by the parent it can be visible through a public import. + child = parentNamespace.getImportedMembership().stream() + .filter(membership -> Objects.equals(membership.getVisibility(), VisibilityKind.PUBLIC)) + .flatMap(membership -> membership.getRelatedElement().stream()) + .filter(elt -> this.nameMatches(elt, qualifiedName.get(0))) + .findFirst(); + } + if (child.isPresent() && qualifiedName.size() > 1) { + element = this.findByQualifiedNameAndTypeFrom(child.get(), qualifiedName.subList(1, qualifiedName.size()), elementType); + } else if (child.isPresent() && elementType.isInstance(child.get())) { + element = elementType.cast(child.get()); + } + return element; + } + + /** + * Iterate over the children of the given root {@link EObject} to find an {@link Element} with the given name and + * type. + * + * @param root + * the root object to iterate. + * @param elementName + * the name to match. + * @param elementType + * the type to match. + * @return the found element or null. + */ + private T findByNameAndTypeFrom(EObject root, String elementName, Class elementType) { + T element = null; + + if (elementType.isInstance(root) && this.nameMatches(elementType.cast(root), elementName)) { + return elementType.cast(root); + } + + TreeIterator eAllContents = root.eAllContents(); + while (eAllContents.hasNext()) { + EObject obj = eAllContents.next(); + if (elementType.isInstance(obj) && this.nameMatches(elementType.cast(obj), elementName)) { + element = elementType.cast(obj); + break; + } + } + + return element; + } + + /** + * Retrieves all the root elements of the resource in the resource set of the given context object. + * + * @param context + * the context object on which to execute this service. + * @return a {@link Collection} of all the root element of the current resource set. + */ + private Collection getAllRootsInResourceSet(EObject context) { + final Resource res = context.eResource(); + if (res != null && res.getResourceSet() != null) { + final Collection roots = new ArrayList<>(); + for (final Resource childRes : res.getResourceSet().getResources()) { + roots.addAll(childRes.getContents()); + } + return roots; + } + return Collections.emptyList(); + } + + /** + * Check if the given element's name match the given String. + * If there is no match with the name, then the short name is checked. + * + * @param element + * the {@link Element} to check. + * @param name + * the name to match. + * @return true if a match is found, false otherwise. + */ + private boolean nameMatches(Element element, String name) { + boolean nameMatches = false; + if (element == null || name == null) { + nameMatches = false; + } else if (this.equalsConsideringOptionalQuotes(element.getName(), name)) { + nameMatches = true; + } else { + nameMatches = this.equalsConsideringOptionalQuotes(element.getShortName(), name); + } + return nameMatches; + } + + private boolean equalsConsideringOptionalQuotes(String candidate, String query) { + if (candidate == null || query == null) { + return false; + } + boolean matches = candidate.strip().equals(query.strip()); + if (!matches && query.startsWith("'") && query.endsWith("'")) { + // We give the option to quote names, but the quotes aren't part of the model. + String tmpCandidate = "'" + candidate + "'"; + matches = tmpCandidate.strip().equals(query.strip()); + } + return matches; + } +} diff --git a/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/util/RedefinesGenerator.java b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/util/RedefinesGenerator.java similarity index 96% rename from backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/util/RedefinesGenerator.java rename to backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/util/RedefinesGenerator.java index adf9ff582..2a8756cf2 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/util/RedefinesGenerator.java +++ b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/util/RedefinesGenerator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024 Obeo. + * Copyright (c) 2024, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.util; +package org.eclipse.syson.sysml.metamodel.util; import java.io.IOException; import java.nio.file.Files; @@ -56,11 +56,8 @@ public class RedefinesGenerator { private final String outputDirectory; - private final String basePackage; - - public RedefinesGenerator(String outputDirectory, String basePackage) { + public RedefinesGenerator(String outputDirectory) { this.outputDirectory = outputDirectory; - this.basePackage = basePackage; } /** @@ -91,7 +88,7 @@ public static void main(String[] args) { Resource viewResource = resourceSet.getResource(sysmlURI, true); List allViewContent = new ArrayList<>(viewResource.getContents()); - var gen = new RedefinesGenerator(args[1], args[2]); + var gen = new RedefinesGenerator(args[1]); StreamSupport.stream(Spliterators.spliterator(allViewContent, Spliterator.ORDERED), false).filter(GenModel.class::isInstance).map(GenModel.class::cast).forEach(model -> { try { @@ -114,10 +111,10 @@ public void doGen(GenModel model) throws IOException { } } - private StringBuilder updatedContentWithSubsetsRedefines(GenClass clazz, String outputDirectory, String fileName) throws IOException { + private StringBuilder updatedContentWithSubsetsRedefines(GenClass clazz, String outputDir, String fileName) throws IOException { StringBuilder body = new StringBuilder(); - if (Files.exists(Path.of(outputDirectory, fileName))) { - body.append(Files.readString(Path.of(outputDirectory, fileName))); + if (Files.exists(Path.of(outputDir, fileName))) { + body.append(Files.readString(Path.of(outputDir, fileName))); } body.replace(body.lastIndexOf("}"), body.length(), ""); for (GenFeature feat : clazz.getGenFeatures()) { @@ -362,7 +359,6 @@ private String genGetRedefinedFeatureBody(GenFeature genFeature, EReference rede if (redefiningFeatureType.startsWith("EList<")) { addOrAddAll = "addAll"; } - String getRedefinedFeatureName = this.genGetRedefinedFeatureName(redefinedFeature); String packageRedefinedFeature = this.getPackageRedefinedFeature(redefinedFeature); body.append(""" #redefinedFeatureType #listName = new BasicEList<>(); diff --git a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/helper/NameHelperTest.java b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/helper/NameHelperTest.java similarity index 75% rename from backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/helper/NameHelperTest.java rename to backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/helper/NameHelperTest.java index 5a0368a3b..8e05d3f71 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/helper/NameHelperTest.java +++ b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/helper/NameHelperTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024, 2025 Obeo. + * Copyright (c) 2024, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.helper; +package org.eclipse.syson.sysml.metamodel.helper; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -27,13 +27,14 @@ public class NameHelperTest { @DisplayName("Test that names containing simple quotes are printed with these simple quotes escpaed.") @Test void testEscapeSimpleQuotes() { - String printableName = NameHelper.toPrintableName("Hello what's up!", true); + var nameHelper = new NameHelper(); + String printableName = nameHelper.toPrintableName("Hello what's up!", true); assertEquals("'Hello what\\'s up!'", printableName); - printableName = NameHelper.toPrintableName("Hello what's up!", false); + printableName = nameHelper.toPrintableName("Hello what's up!", false); assertEquals("'Hello what's up!'", printableName); - printableName = NameHelper.toPrintableName("Hel'lo", true); + printableName = nameHelper.toPrintableName("Hel'lo", true); assertEquals("'Hel\\'lo'", printableName); - printableName = NameHelper.toPrintableName("Hel'lo", false); + printableName = nameHelper.toPrintableName("Hel'lo", false); assertEquals("'Hel'lo'", printableName); } } diff --git a/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/ElementInitializerSwitchTest.java b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/ElementInitializerSwitchTest.java index 97f12bfe7..60714315f 100644 --- a/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/ElementInitializerSwitchTest.java +++ b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/ElementInitializerSwitchTest.java @@ -27,7 +27,7 @@ import org.eclipse.syson.sysml.SysmlFactory; import org.eclipse.syson.sysml.SysmlPackage; import org.eclipse.syson.sysml.VisibilityKind; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/FileNameDeresolverTest.java b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/FileNameDeresolverTest.java similarity index 99% rename from backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/FileNameDeresolverTest.java rename to backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/FileNameDeresolverTest.java index f292b8545..5c94bf768 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/FileNameDeresolverTest.java +++ b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/FileNameDeresolverTest.java @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.textual; +package org.eclipse.syson.sysml.metamodel.services.textual; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -26,7 +26,7 @@ import org.eclipse.syson.sysml.PerformActionUsage; import org.eclipse.syson.sysml.VerificationCaseUsage; import org.eclipse.syson.sysml.VisibilityKind; -import org.eclipse.syson.sysml.textual.utils.FileNameDeresolver; +import org.eclipse.syson.sysml.metamodel.services.textual.utils.FileNameDeresolver; import org.eclipse.syson.sysml.util.ModelBuilder; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; diff --git a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/AssertConstraintUsageWithOperatorExpressionTestModel.java b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/AssertConstraintUsageWithOperatorExpressionTestModel.java similarity index 98% rename from backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/AssertConstraintUsageWithOperatorExpressionTestModel.java rename to backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/AssertConstraintUsageWithOperatorExpressionTestModel.java index 4e499a39f..a2acb8b47 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/AssertConstraintUsageWithOperatorExpressionTestModel.java +++ b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/AssertConstraintUsageWithOperatorExpressionTestModel.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024, 2025 Obeo. + * Copyright (c) 2024, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.textual.models; +package org.eclipse.syson.sysml.metamodel.services.textual.models; import org.eclipse.syson.sysml.AssertConstraintUsage; import org.eclipse.syson.sysml.Expression; diff --git a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/AttributeUsageWithBinaryOperatorExpressionTestModel.java b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/AttributeUsageWithBinaryOperatorExpressionTestModel.java similarity index 97% rename from backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/AttributeUsageWithBinaryOperatorExpressionTestModel.java rename to backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/AttributeUsageWithBinaryOperatorExpressionTestModel.java index dc46138f4..d67bfb8fe 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/AttributeUsageWithBinaryOperatorExpressionTestModel.java +++ b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/AttributeUsageWithBinaryOperatorExpressionTestModel.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024, 2025 Obeo. + * Copyright (c) 2024, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.textual.models; +package org.eclipse.syson.sysml.metamodel.services.textual.models; import org.eclipse.syson.sysml.AttributeUsage; import org.eclipse.syson.sysml.Feature; diff --git a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/AttributeUsageWithBracketOperatorExpressionTestModel.java b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/AttributeUsageWithBracketOperatorExpressionTestModel.java similarity index 97% rename from backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/AttributeUsageWithBracketOperatorExpressionTestModel.java rename to backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/AttributeUsageWithBracketOperatorExpressionTestModel.java index 6ef3da728..f5950f7ca 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/AttributeUsageWithBracketOperatorExpressionTestModel.java +++ b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/AttributeUsageWithBracketOperatorExpressionTestModel.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024, 2025 Obeo. + * Copyright (c) 2024, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.textual.models; +package org.eclipse.syson.sysml.metamodel.services.textual.models; import org.eclipse.syson.sysml.AttributeUsage; import org.eclipse.syson.sysml.Feature; diff --git a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/AttributeUsageWithFeatureChainExpressionTestModel.java b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/AttributeUsageWithFeatureChainExpressionTestModel.java similarity index 98% rename from backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/AttributeUsageWithFeatureChainExpressionTestModel.java rename to backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/AttributeUsageWithFeatureChainExpressionTestModel.java index 3a59399b5..ad7e2518d 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/AttributeUsageWithFeatureChainExpressionTestModel.java +++ b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/AttributeUsageWithFeatureChainExpressionTestModel.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024, 2025 Obeo. + * Copyright (c) 2024, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.textual.models; +package org.eclipse.syson.sysml.metamodel.services.textual.models; import org.eclipse.syson.sysml.AttributeUsage; import org.eclipse.syson.sysml.Feature; diff --git a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/AttributeUsageWithInvocationExpressionTestModel.java b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/AttributeUsageWithInvocationExpressionTestModel.java similarity index 96% rename from backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/AttributeUsageWithInvocationExpressionTestModel.java rename to backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/AttributeUsageWithInvocationExpressionTestModel.java index 6a0154f95..02dab778d 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/AttributeUsageWithInvocationExpressionTestModel.java +++ b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/AttributeUsageWithInvocationExpressionTestModel.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024, 2025 Obeo. + * Copyright (c) 2024, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.textual.models; +package org.eclipse.syson.sysml.metamodel.services.textual.models; import org.eclipse.syson.sysml.AttributeUsage; import org.eclipse.syson.sysml.Feature; diff --git a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/AttributeUsageWithSequenceExpressionTestModel.java b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/AttributeUsageWithSequenceExpressionTestModel.java similarity index 98% rename from backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/AttributeUsageWithSequenceExpressionTestModel.java rename to backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/AttributeUsageWithSequenceExpressionTestModel.java index f56e0a57d..32cef4471 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/AttributeUsageWithSequenceExpressionTestModel.java +++ b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/AttributeUsageWithSequenceExpressionTestModel.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024, 2025 Obeo. + * Copyright (c) 2024, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.textual.models; +package org.eclipse.syson.sysml.metamodel.services.textual.models; import org.eclipse.syson.sysml.AttributeUsage; import org.eclipse.syson.sysml.Feature; diff --git a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/ConditionalBinaryOperatorExpressionTestModel.java b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/ConditionalBinaryOperatorExpressionTestModel.java similarity index 97% rename from backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/ConditionalBinaryOperatorExpressionTestModel.java rename to backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/ConditionalBinaryOperatorExpressionTestModel.java index da51db30e..1ffd49109 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/ConditionalBinaryOperatorExpressionTestModel.java +++ b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/ConditionalBinaryOperatorExpressionTestModel.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024, 2025 Obeo. + * Copyright (c) 2024, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.textual.models; +package org.eclipse.syson.sysml.metamodel.services.textual.models; import org.eclipse.syson.sysml.Element; import org.eclipse.syson.sysml.Expression; diff --git a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/ConstraintUsageWithOperatorExpressionTestModel.java b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/ConstraintUsageWithOperatorExpressionTestModel.java similarity index 98% rename from backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/ConstraintUsageWithOperatorExpressionTestModel.java rename to backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/ConstraintUsageWithOperatorExpressionTestModel.java index 8eee17c18..8a864676f 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/ConstraintUsageWithOperatorExpressionTestModel.java +++ b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/ConstraintUsageWithOperatorExpressionTestModel.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024, 2025 Obeo. + * Copyright (c) 2024, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.textual.models; +package org.eclipse.syson.sysml.metamodel.services.textual.models; import org.eclipse.syson.sysml.ConstraintUsage; import org.eclipse.syson.sysml.Expression; diff --git a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/IsImplicitTest.java b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/IsImplicitTest.java similarity index 97% rename from backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/IsImplicitTest.java rename to backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/IsImplicitTest.java index 498de1568..75b22aeac 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/IsImplicitTest.java +++ b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/IsImplicitTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024, 2025 Obeo. + * Copyright (c) 2024, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.textual.models; +package org.eclipse.syson.sysml.metamodel.services.textual.models; import org.eclipse.syson.sysml.ObjectiveMembership; import org.eclipse.syson.sysml.Redefinition; diff --git a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/UseCaseDefinitionTestModel.java b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/UseCaseDefinitionTestModel.java similarity index 97% rename from backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/UseCaseDefinitionTestModel.java rename to backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/UseCaseDefinitionTestModel.java index de24d6731..d9ebe0009 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/UseCaseDefinitionTestModel.java +++ b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/UseCaseDefinitionTestModel.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024, 2025 Obeo. + * Copyright (c) 2024, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.textual.models; +package org.eclipse.syson.sysml.metamodel.services.textual.models; import org.eclipse.syson.sysml.ActorMembership; import org.eclipse.syson.sysml.ObjectiveMembership; diff --git a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/sample/CameraModel.java b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/sample/CameraModel.java similarity index 98% rename from backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/sample/CameraModel.java rename to backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/sample/CameraModel.java index 3a1ca7a2e..09e5f857a 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/sample/CameraModel.java +++ b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/sample/CameraModel.java @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.textual.models.sample; +package org.eclipse.syson.sysml.metamodel.services.textual.models.sample; import org.eclipse.syson.sysml.Feature; import org.eclipse.syson.sysml.NamespaceImport; diff --git a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/sample/ItemTest.java b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/sample/ItemTest.java similarity index 98% rename from backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/sample/ItemTest.java rename to backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/sample/ItemTest.java index 04eb1e804..90c65031b 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/sample/ItemTest.java +++ b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/sample/ItemTest.java @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.textual.models.sample; +package org.eclipse.syson.sysml.metamodel.services.textual.models.sample; import org.eclipse.syson.sysml.FeatureDirectionKind; import org.eclipse.syson.sysml.ItemDefinition; diff --git a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/sample/PictureTakingModel.java b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/sample/PictureTakingModel.java similarity index 97% rename from backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/sample/PictureTakingModel.java rename to backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/sample/PictureTakingModel.java index b0c5181d0..15e72fb54 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/textual/models/sample/PictureTakingModel.java +++ b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/services/textual/models/sample/PictureTakingModel.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024, 2025 Obeo. + * Copyright (c) 2024, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.textual.models.sample; +package org.eclipse.syson.sysml.metamodel.services.textual.models.sample; import org.eclipse.syson.sysml.ActionDefinition; import org.eclipse.syson.sysml.ActionUsage; diff --git a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/metamodel/ElementUtilTest.java b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/util/ElementUtilTest.java similarity index 96% rename from backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/metamodel/ElementUtilTest.java rename to backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/util/ElementUtilTest.java index a8b451555..e72f19b41 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/metamodel/ElementUtilTest.java +++ b/backend/services/syson-sysml-metamodel-services/src/test/java/org/eclipse/syson/sysml/metamodel/util/ElementUtilTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024, 2025 Obeo. + * Copyright (c) 2024, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.sysml.metamodel; +package org.eclipse.syson.sysml.metamodel.util; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -22,7 +22,6 @@ import org.eclipse.syson.sysml.LibraryPackage; import org.eclipse.syson.sysml.OwningMembership; import org.eclipse.syson.sysml.SysmlFactory; -import org.eclipse.syson.sysml.util.ElementUtil; import org.eclipse.syson.sysml.util.SysmlResourceImpl; import org.junit.jupiter.api.Test; diff --git a/backend/services/syson-sysml-rest-api-services/src/main/java/org/eclipse/syson/sysml/rest/api/SysMLv2JsonSerializer.java b/backend/services/syson-sysml-rest-api-services/src/main/java/org/eclipse/syson/sysml/rest/api/SysMLv2JsonSerializer.java index 32c8445b0..f76ba12db 100644 --- a/backend/services/syson-sysml-rest-api-services/src/main/java/org/eclipse/syson/sysml/rest/api/SysMLv2JsonSerializer.java +++ b/backend/services/syson-sysml-rest-api-services/src/main/java/org/eclipse/syson/sysml/rest/api/SysMLv2JsonSerializer.java @@ -24,7 +24,7 @@ import org.eclipse.emf.ecore.EcorePackage; import org.eclipse.sirius.components.emf.services.EObjectIDManager; import org.eclipse.syson.sysml.Element; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.eclipse.syson.sysml.util.VirtualLinkAdapter; import tools.jackson.core.JacksonException; diff --git a/backend/services/syson-sysml-rest-api-services/src/main/java/org/eclipse/syson/sysml/rest/api/SysONObjectRestService.java b/backend/services/syson-sysml-rest-api-services/src/main/java/org/eclipse/syson/sysml/rest/api/SysONObjectRestService.java index 16cf8e458..b36b775df 100644 --- a/backend/services/syson-sysml-rest-api-services/src/main/java/org/eclipse/syson/sysml/rest/api/SysONObjectRestService.java +++ b/backend/services/syson-sysml-rest-api-services/src/main/java/org/eclipse/syson/sysml/rest/api/SysONObjectRestService.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024, 2025 Obeo. + * Copyright (c) 2024, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -32,7 +32,7 @@ import org.eclipse.syson.services.UtilService; import org.eclipse.syson.sysml.Element; import org.eclipse.syson.sysml.Relationship; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.springframework.stereotype.Service; /** diff --git a/backend/services/syson-tree-services/src/main/java/org/eclipse/syson/tree/explorer/services/SysONDefaultExplorerServices.java b/backend/services/syson-tree-services/src/main/java/org/eclipse/syson/tree/explorer/services/SysONDefaultExplorerServices.java index 906e39d7b..1f63e0aff 100644 --- a/backend/services/syson-tree-services/src/main/java/org/eclipse/syson/tree/explorer/services/SysONDefaultExplorerServices.java +++ b/backend/services/syson-tree-services/src/main/java/org/eclipse/syson/tree/explorer/services/SysONDefaultExplorerServices.java @@ -42,10 +42,10 @@ import org.eclipse.syson.sysml.Type; import org.eclipse.syson.sysml.ViewUsage; import org.eclipse.syson.sysml.metamodel.services.MetamodelQueryElementService; -import org.eclipse.syson.sysml.textual.SysMLElementSerializer; -import org.eclipse.syson.sysml.textual.SysMLSerializingOptions; -import org.eclipse.syson.sysml.textual.utils.FileNameDeresolver; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.services.textual.SysMLElementSerializer; +import org.eclipse.syson.sysml.metamodel.services.textual.SysMLSerializingOptions; +import org.eclipse.syson.sysml.metamodel.services.textual.utils.FileNameDeresolver; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.eclipse.syson.tree.explorer.fragments.KerMLStandardLibraryDirectory; import org.eclipse.syson.tree.explorer.fragments.LibrariesDirectory; import org.eclipse.syson.tree.explorer.fragments.SysMLStandardLibraryDirectory; diff --git a/backend/services/syson-tree-services/src/main/java/org/eclipse/syson/tree/explorer/services/SysONExplorerFilterService.java b/backend/services/syson-tree-services/src/main/java/org/eclipse/syson/tree/explorer/services/SysONExplorerFilterService.java index d4bb946de..07795b306 100644 --- a/backend/services/syson-tree-services/src/main/java/org/eclipse/syson/tree/explorer/services/SysONExplorerFilterService.java +++ b/backend/services/syson-tree-services/src/main/java/org/eclipse/syson/tree/explorer/services/SysONExplorerFilterService.java @@ -26,7 +26,7 @@ import org.eclipse.syson.sysml.Membership; import org.eclipse.syson.sysml.Namespace; import org.eclipse.syson.sysml.metamodel.services.MetamodelQueryElementService; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.eclipse.syson.tree.explorer.filters.SysONTreeFilterConstants; import org.eclipse.syson.tree.explorer.services.api.ISysONExplorerFilterService; import org.springframework.stereotype.Service; diff --git a/backend/services/syson-tree-services/src/test/java/org/eclipse/syson/tree/explorer/services/SysONExplorerFilterServiceTest.java b/backend/services/syson-tree-services/src/test/java/org/eclipse/syson/tree/explorer/services/SysONExplorerFilterServiceTest.java index 7d2ca4ba0..4bbd9216c 100644 --- a/backend/services/syson-tree-services/src/test/java/org/eclipse/syson/tree/explorer/services/SysONExplorerFilterServiceTest.java +++ b/backend/services/syson-tree-services/src/test/java/org/eclipse/syson/tree/explorer/services/SysONExplorerFilterServiceTest.java @@ -29,7 +29,7 @@ import org.eclipse.syson.sysml.Namespace; import org.eclipse.syson.sysml.PartUsage; import org.eclipse.syson.sysml.SysmlFactory; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.eclipse.syson.tree.explorer.services.api.ISysONExplorerFilterService; import org.junit.jupiter.api.Test; diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractAllocateEdgeDescriptionProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractAllocateEdgeDescriptionProvider.java index d5dc33fa7..de5d1d818 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractAllocateEdgeDescriptionProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractAllocateEdgeDescriptionProvider.java @@ -26,7 +26,7 @@ import org.eclipse.sirius.components.view.diagram.SynchronizationPolicy; import org.eclipse.syson.diagram.common.view.services.ViewEdgeService; import org.eclipse.syson.sysml.SysmlPackage; -import org.eclipse.syson.sysml.helper.LabelConstants; +import org.eclipse.syson.sysml.metamodel.helper.LabelConstants; import org.eclipse.syson.util.AQLConstants; import org.eclipse.syson.util.ServiceMethod; import org.eclipse.syson.util.SysMLMetamodelHelper; diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewCreateService.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewCreateService.java index 8bb066b2e..d4582e6b3 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewCreateService.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewCreateService.java @@ -85,7 +85,7 @@ import org.eclipse.syson.sysml.UseCaseUsage; import org.eclipse.syson.sysml.metamodel.services.ElementInitializerSwitch; import org.eclipse.syson.sysml.metamodel.services.MetamodelMutationElementService; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.eclipse.syson.util.NodeFinder; /** diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewLabelService.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewLabelService.java index 90723a381..1101fc00d 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewLabelService.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewLabelService.java @@ -20,8 +20,8 @@ import org.eclipse.sirius.components.representations.MessageLevel; import org.eclipse.syson.services.SimpleNameDeresolver; import org.eclipse.syson.sysml.Element; -import org.eclipse.syson.sysml.textual.SysMLElementSerializer; -import org.eclipse.syson.sysml.textual.SysMLSerializingOptions; +import org.eclipse.syson.sysml.metamodel.services.textual.SysMLElementSerializer; +import org.eclipse.syson.sysml.metamodel.services.textual.SysMLSerializingOptions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/backend/views/syson-diagram-tests/src/main/java/org/eclipse/syson/diagram/tests/checkers/AQLExpressionCallsExistingServicesChecker.java b/backend/views/syson-diagram-tests/src/main/java/org/eclipse/syson/diagram/tests/checkers/AQLExpressionCallsExistingServicesChecker.java index e33824fd0..76e29de02 100644 --- a/backend/views/syson-diagram-tests/src/main/java/org/eclipse/syson/diagram/tests/checkers/AQLExpressionCallsExistingServicesChecker.java +++ b/backend/views/syson-diagram-tests/src/main/java/org/eclipse/syson/diagram/tests/checkers/AQLExpressionCallsExistingServicesChecker.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024 Obeo. + * Copyright (c) 2024, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -27,7 +27,7 @@ import org.eclipse.acceleo.query.runtime.Query; import org.eclipse.acceleo.query.runtime.QueryParsing; import org.eclipse.sirius.components.interpreter.SimpleCrossReferenceProvider; -import org.eclipse.syson.sysml.helper.EMFUtils; +import org.eclipse.syson.sysml.metamodel.helper.EMFUtils; /** * Checks that the provided AQL expression contains services that are either default services or diagram services. diff --git a/backend/views/syson-diagram-tests/src/main/java/org/eclipse/syson/diagram/tests/checkers/NodeDescriptionIsReusedByChecker.java b/backend/views/syson-diagram-tests/src/main/java/org/eclipse/syson/diagram/tests/checkers/NodeDescriptionIsReusedByChecker.java index bfda5500d..700e7d80e 100644 --- a/backend/views/syson-diagram-tests/src/main/java/org/eclipse/syson/diagram/tests/checkers/NodeDescriptionIsReusedByChecker.java +++ b/backend/views/syson-diagram-tests/src/main/java/org/eclipse/syson/diagram/tests/checkers/NodeDescriptionIsReusedByChecker.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024 Obeo. + * Copyright (c) 2024, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -19,7 +19,7 @@ import org.eclipse.sirius.components.view.diagram.DiagramDescription; import org.eclipse.sirius.components.view.diagram.NodeDescription; -import org.eclipse.syson.sysml.helper.EMFUtils; +import org.eclipse.syson.sysml.metamodel.helper.EMFUtils; /** * Checks that the provided {@link NodeDescription} is reused by the expected elements. diff --git a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/edges/FrameConcernEdgeDescriptionProvider.java b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/edges/FrameConcernEdgeDescriptionProvider.java index eeca4f992..602ef2a0f 100644 --- a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/edges/FrameConcernEdgeDescriptionProvider.java +++ b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/edges/FrameConcernEdgeDescriptionProvider.java @@ -33,7 +33,7 @@ import org.eclipse.syson.services.DeleteService; import org.eclipse.syson.services.UtilService; import org.eclipse.syson.sysml.SysmlPackage; -import org.eclipse.syson.sysml.helper.LabelConstants; +import org.eclipse.syson.sysml.metamodel.helper.LabelConstants; import org.eclipse.syson.util.AQLConstants; import org.eclipse.syson.util.IDescriptionNameGenerator; import org.eclipse.syson.util.ServiceMethod; diff --git a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/edges/IncludeUseCaseDescriptionProvider.java b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/edges/IncludeUseCaseDescriptionProvider.java index e8eae7fee..640368ec0 100644 --- a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/edges/IncludeUseCaseDescriptionProvider.java +++ b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/edges/IncludeUseCaseDescriptionProvider.java @@ -32,7 +32,7 @@ import org.eclipse.syson.services.UtilService; import org.eclipse.syson.sysml.IncludeUseCaseUsage; import org.eclipse.syson.sysml.SysmlPackage; -import org.eclipse.syson.sysml.helper.LabelConstants; +import org.eclipse.syson.sysml.metamodel.helper.LabelConstants; import org.eclipse.syson.util.AQLConstants; import org.eclipse.syson.util.IDescriptionNameGenerator; import org.eclipse.syson.util.ServiceMethod; diff --git a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/services/SysONShowHideSDVElementEventHandler.java b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/services/SysONShowHideSDVElementEventHandler.java index c14ff107c..660fc9cd2 100644 --- a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/services/SysONShowHideSDVElementEventHandler.java +++ b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/services/SysONShowHideSDVElementEventHandler.java @@ -42,7 +42,7 @@ import org.eclipse.sirius.web.domain.boundedcontexts.representationdata.services.api.IRepresentationMetadataSearchService; import org.eclipse.sirius.web.domain.boundedcontexts.semanticdata.SemanticData; import org.eclipse.syson.standard.diagrams.view.SDVDescriptionNameGenerator; -import org.eclipse.syson.sysml.helper.EMFUtils; +import org.eclipse.syson.sysml.metamodel.helper.EMFUtils; import org.eclipse.syson.util.NodeFinder; import org.eclipse.syson.util.SysONRepresentationDescriptionIdentifiers; import org.springframework.core.Ordered; diff --git a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/services/nodeactions/managevisibility/ManageVisibilityNodeActionProvider.java b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/services/nodeactions/managevisibility/ManageVisibilityNodeActionProvider.java index dcf6b6b83..17535bbd7 100644 --- a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/services/nodeactions/managevisibility/ManageVisibilityNodeActionProvider.java +++ b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/services/nodeactions/managevisibility/ManageVisibilityNodeActionProvider.java @@ -30,7 +30,7 @@ import org.eclipse.syson.standard.diagrams.view.SDVDiagramDescriptionProvider; import org.eclipse.syson.sysml.Definition; import org.eclipse.syson.sysml.Usage; -import org.eclipse.syson.sysml.helper.EMFUtils; +import org.eclipse.syson.sysml.metamodel.helper.EMFUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/backend/views/syson-standard-diagrams-view/src/test/java/org/eclipse/syson/standard/diagrams/view/SDVDiagramDescriptionTests.java b/backend/views/syson-standard-diagrams-view/src/test/java/org/eclipse/syson/standard/diagrams/view/SDVDiagramDescriptionTests.java index 5c3a1248a..6ce3f7424 100644 --- a/backend/views/syson-standard-diagrams-view/src/test/java/org/eclipse/syson/standard/diagrams/view/SDVDiagramDescriptionTests.java +++ b/backend/views/syson-standard-diagrams-view/src/test/java/org/eclipse/syson/standard/diagrams/view/SDVDiagramDescriptionTests.java @@ -42,7 +42,7 @@ import org.eclipse.syson.diagram.tests.predicates.DiagramPredicates; import org.eclipse.syson.services.ColorProvider; import org.eclipse.syson.sysml.SysmlPackage; -import org.eclipse.syson.sysml.helper.EMFUtils; +import org.eclipse.syson.sysml.metamodel.helper.EMFUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/backend/views/syson-tree-explorer-view/src/main/java/org/eclipse/syson/tree/explorer/view/menu/context/CreateRepresentationInputProcessor.java b/backend/views/syson-tree-explorer-view/src/main/java/org/eclipse/syson/tree/explorer/view/menu/context/CreateRepresentationInputProcessor.java index c3e9a1835..c60d3e191 100644 --- a/backend/views/syson-tree-explorer-view/src/main/java/org/eclipse/syson/tree/explorer/view/menu/context/CreateRepresentationInputProcessor.java +++ b/backend/views/syson-tree-explorer-view/src/main/java/org/eclipse/syson/tree/explorer/view/menu/context/CreateRepresentationInputProcessor.java @@ -29,7 +29,7 @@ import org.eclipse.syson.sysml.SysmlFactory; import org.eclipse.syson.sysml.ViewDefinition; import org.eclipse.syson.sysml.ViewUsage; -import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.sysml.metamodel.util.ElementUtil; import org.eclipse.syson.util.StandardDiagramsConstants; import org.eclipse.syson.util.SysONRepresentationDescriptionIdentifiers; import org.springframework.stereotype.Service; diff --git a/backend/views/syson-tree-explorer-view/src/test/java/org/eclipse/syson/tree/explorer/view/duplicate/SysMLContainmentMembershipLabelSwitchTest.java b/backend/views/syson-tree-explorer-view/src/test/java/org/eclipse/syson/tree/explorer/view/duplicate/SysMLContainmentMembershipLabelSwitchTest.java index 8a76b8c46..c36c98bf2 100644 --- a/backend/views/syson-tree-explorer-view/src/test/java/org/eclipse/syson/tree/explorer/view/duplicate/SysMLContainmentMembershipLabelSwitchTest.java +++ b/backend/views/syson-tree-explorer-view/src/test/java/org/eclipse/syson/tree/explorer/view/duplicate/SysMLContainmentMembershipLabelSwitchTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2025 Obeo. + * Copyright (c) 2025, 2026 Obeo. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -18,7 +18,7 @@ import org.eclipse.emf.ecore.EClass; import org.eclipse.syson.sysml.SysmlPackage; -import org.eclipse.syson.sysml.helper.EMFUtils; +import org.eclipse.syson.sysml.metamodel.helper.EMFUtils; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/pom.xml b/pom.xml index 1cadcbf33..bf202440a 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,6 @@