diff --git a/backend/application/syson-application/src/test/java/org/eclipse/syson/application/data/GeneralViewWithTopNodesTestProjectData.java b/backend/application/syson-application/src/test/java/org/eclipse/syson/application/data/GeneralViewWithTopNodesTestProjectData.java index 93b94a439..2922669f8 100644 --- a/backend/application/syson-application/src/test/java/org/eclipse/syson/application/data/GeneralViewWithTopNodesTestProjectData.java +++ b/backend/application/syson-application/src/test/java/org/eclipse/syson/application/data/GeneralViewWithTopNodesTestProjectData.java @@ -65,6 +65,8 @@ public static final class SemanticIds { public static final String ACTION_USAGE_ID = "62481ceb-d036-4723-acda-2bace93ae370"; public static final String ACTION_DEFINITION_ID = "b918a8a1-f30b-4703-b131-77cde928401d"; + + public static final String OCCURRENCE_USAGE_ID = "5126fb57-f6b3-4d0c-b981-92cfc961091f"; } } diff --git a/backend/application/syson-application/src/test/java/org/eclipse/syson/metamodel/helper/ImplicitSpecializationsTests.java b/backend/application/syson-application/src/test/java/org/eclipse/syson/metamodel/helper/ImplicitSpecializationsTests.java index 942858a47..3b8d79a22 100644 --- a/backend/application/syson-application/src/test/java/org/eclipse/syson/metamodel/helper/ImplicitSpecializationsTests.java +++ b/backend/application/syson-application/src/test/java/org/eclipse/syson/metamodel/helper/ImplicitSpecializationsTests.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 @@ -13,6 +13,7 @@ package org.eclipse.syson.metamodel.helper; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import java.time.Duration; @@ -21,37 +22,36 @@ import java.util.Optional; import java.util.UUID; -import org.eclipse.sirius.components.collaborative.diagrams.dto.DiagramEventInput; -import org.eclipse.sirius.components.collaborative.diagrams.dto.DiagramRefreshedEventPayload; +import org.eclipse.sirius.components.collaborative.dto.EditingContextEventInput; import org.eclipse.sirius.components.core.api.IObjectSearchService; +import org.eclipse.sirius.components.graphql.tests.EditingContextEventSubscriptionRunner; +import org.eclipse.sirius.components.graphql.tests.ExecuteEditingContextFunctionSuccessPayload; import org.eclipse.sirius.web.tests.services.api.IGivenInitialServerState; import org.eclipse.syson.AbstractIntegrationTests; +import org.eclipse.syson.GivenSysONServer; import org.eclipse.syson.application.controller.editingContext.checkers.ISemanticChecker; import org.eclipse.syson.application.controller.editingContext.checkers.SemanticCheckerService; import org.eclipse.syson.application.data.GeneralViewWithTopNodesTestProjectData; import org.eclipse.syson.services.SemanticRunnableFactory; -import org.eclipse.syson.services.diagrams.api.IGivenDiagramSubscription; import org.eclipse.syson.sysml.AcceptActionUsage; import org.eclipse.syson.sysml.ActionUsage; import org.eclipse.syson.sysml.Element; +import org.eclipse.syson.sysml.OccurrenceUsage; import org.eclipse.syson.sysml.PartDefinition; import org.eclipse.syson.sysml.PartUsage; +import org.eclipse.syson.sysml.PortionKind; import org.eclipse.syson.sysml.Redefinition; import org.eclipse.syson.sysml.Specialization; import org.eclipse.syson.sysml.SysmlFactory; import org.eclipse.syson.sysml.helper.EMFUtils; -import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.jdbc.Sql; -import org.springframework.test.context.jdbc.SqlConfig; import org.springframework.transaction.annotation.Transactional; import reactor.test.StepVerifier; -import reactor.test.StepVerifier.Step; /** * Tests the implicit specializations of SysMLv2 elements. We need an integration test to benefit from the standard @@ -59,6 +59,7 @@ * * @author arichard */ +@SuppressWarnings("checkstyle:MultipleStringLiterals") @Transactional @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class ImplicitSpecializationsTests extends AbstractIntegrationTests { @@ -67,7 +68,7 @@ public class ImplicitSpecializationsTests extends AbstractIntegrationTests { private IGivenInitialServerState givenInitialServerState; @Autowired - private IGivenDiagramSubscription givenDiagramSubscription; + private EditingContextEventSubscriptionRunner editingContextEventSubscriptionRunner; @Autowired private IObjectSearchService objectSearchService; @@ -75,36 +76,20 @@ public class ImplicitSpecializationsTests extends AbstractIntegrationTests { @Autowired private SemanticRunnableFactory semanticRunnableFactory; - private Step verifier; - - private SemanticCheckerService semanticCheckerService; - @BeforeEach public void setUp() { this.givenInitialServerState.initialize(); - var diagramEventInput = new DiagramEventInput(UUID.randomUUID(), - GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID, - GeneralViewWithTopNodesTestProjectData.GraphicalIds.DIAGRAM_ID); - var flux = this.givenDiagramSubscription.subscribe(diagramEventInput); - this.verifier = StepVerifier.create(flux); - this.semanticCheckerService = new SemanticCheckerService(this.semanticRunnableFactory, this.objectSearchService, GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID, - GeneralViewWithTopNodesTestProjectData.SemanticIds.PACKAGE_1_ID); - } - - @AfterEach - public void tearDown() { - if (this.verifier != null) { - this.verifier.thenCancel() - .verify(Duration.ofSeconds(1)); - } } - @DisplayName("GIVEN a PartUsage with or without Specialization (FeatureTyping, Susbetting or Redefinition), WHEN validation is executed, THEN the Part implictly specializes 'Parts::parts' from the standard libraries.") - @Sql(scripts = { GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH }, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, - config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) - @Sql(scripts = { "/scripts/cleanup.sql" }, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + @DisplayName("GIVEN a PartUsage with or without Specialization (FeatureTyping, Subsetting or Redefinition), WHEN validation is executed, THEN the Part implicitly specializes 'Parts::parts' from the standard libraries.") + @GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH }) @Test public void testImplicitSpecializationOnPartUsage() { + var semanticCheckerService = new SemanticCheckerService(this.semanticRunnableFactory, this.objectSearchService, GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID, + GeneralViewWithTopNodesTestProjectData.SemanticIds.PACKAGE_1_ID); + var editingContextEventInput = new EditingContextEventInput(UUID.randomUUID(), GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID); + var flux = this.editingContextEventSubscriptionRunner.run(editingContextEventInput).flux(); + ISemanticChecker semanticChecker = (editingContext) -> { Object semanticRootObject = this.objectSearchService.getObject(editingContext, GeneralViewWithTopNodesTestProjectData.SemanticIds.PACKAGE_1_ID).orElse(null); assertThat(semanticRootObject).isInstanceOf(Element.class); @@ -149,15 +134,21 @@ public void testImplicitSpecializationOnPartUsage() { assertTrue(anotherPart.specializesFromLibrary("Parts::Part")); }; - this.semanticCheckerService.checkEditingContext(semanticChecker, this.verifier); + StepVerifier.create(flux) + .then(semanticCheckerService.checkEditingContext(semanticChecker)) + .thenCancel() + .verify(Duration.ofSeconds(10)); } - @DisplayName("GIVEN an AcceptAction, WHEN the validation is executed, THEN the AcceptAction implictly specializes 'Actions::acceptActions'") - @Sql(scripts = { GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH }, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, - config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) - @Sql(scripts = { "/scripts/cleanup.sql" }, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + @DisplayName("GIVEN an AcceptAction, WHEN the validation is executed, THEN the AcceptAction implicitly specializes 'Actions::acceptActions'") + @GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH }) @Test public void testImplicitSpecializationOnAcceptActionUsage() { + var semanticCheckerService = new SemanticCheckerService(this.semanticRunnableFactory, this.objectSearchService, GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID, + GeneralViewWithTopNodesTestProjectData.SemanticIds.PACKAGE_1_ID); + var editingContextEventInput = new EditingContextEventInput(UUID.randomUUID(), GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID); + var flux = this.editingContextEventSubscriptionRunner.run(editingContextEventInput).flux(); + ISemanticChecker semanticChecker = (editingContext) -> { Object semanticRootObject = this.objectSearchService.getObject(editingContext, GeneralViewWithTopNodesTestProjectData.SemanticIds.PACKAGE_1_ID).orElse(null); assertThat(semanticRootObject).isInstanceOf(Element.class); @@ -171,15 +162,21 @@ public void testImplicitSpecializationOnAcceptActionUsage() { assertTrue(acceptActionUsage.specializesFromLibrary("Actions::acceptActions")); }; - this.semanticCheckerService.checkEditingContext(semanticChecker, this.verifier); + StepVerifier.create(flux) + .then(semanticCheckerService.checkEditingContext(semanticChecker)) + .thenCancel() + .verify(Duration.ofSeconds(10)); } @DisplayName("GIVEN a parameter of an ActionUsage that subsets another ActionUsage with parameters, WHEN the validation is executed, THEN the ActionUsgae implicitly redefines the corresponding parameter") - @Sql(scripts = { GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH }, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, - config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) - @Sql(scripts = { "/scripts/cleanup.sql" }, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + @GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH }) @Test public void testImplicitParameterRedefinitionOnItemUsage() { + var semanticCheckerService = new SemanticCheckerService(this.semanticRunnableFactory, this.objectSearchService, GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID, + GeneralViewWithTopNodesTestProjectData.SemanticIds.PACKAGE_1_ID); + var editingContextEventInput = new EditingContextEventInput(UUID.randomUUID(), GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID); + var flux = this.editingContextEventSubscriptionRunner.run(editingContextEventInput).flux(); + ISemanticChecker semanticChecker = (editingContext) -> { Object semanticRootObject = this.objectSearchService.getObject(editingContext, GeneralViewWithTopNodesTestProjectData.SemanticIds.PACKAGE_1_ID).orElse(null); assertThat(semanticRootObject).isInstanceOf(Element.class); @@ -207,6 +204,86 @@ public void testImplicitParameterRedefinitionOnItemUsage() { .extracting(Redefinition::getRedefinedFeature) .isEqualTo(parentActionWithParameter.getParameter().get(0)); }; - this.semanticCheckerService.checkEditingContext(semanticChecker, this.verifier); + + StepVerifier.create(flux) + .then(semanticCheckerService.checkEditingContext(semanticChecker)) + .thenCancel() + .verify(Duration.ofSeconds(10)); + } + + @DisplayName("GIVEN a timeslice Part, WHEN the validation is executed, THEN the Part implicitly specializes 'Occurrences::Occurrence::timeSlices'") + @GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH }) + @Test + public void testImplicitTimeSliceSpecializationOnPartUsage() { + var semanticCheckerService = new SemanticCheckerService(this.semanticRunnableFactory, this.objectSearchService, GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID, + GeneralViewWithTopNodesTestProjectData.SemanticIds.PACKAGE_1_ID); + + var editingContextEventInput = new EditingContextEventInput(UUID.randomUUID(), GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID); + var flux = this.editingContextEventSubscriptionRunner.run(editingContextEventInput).flux(); + + var initializeEditingContext = this.semanticRunnableFactory.createRunnable(GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID, (editingContext, executeEditingContextFunctionInput) -> { + var optionalPartUsage = this.objectSearchService.getObject(editingContext, GeneralViewWithTopNodesTestProjectData.SemanticIds.PART_USAGE_ID) + .filter(PartUsage.class::isInstance) + .map(PartUsage.class::cast); + assertThat(optionalPartUsage).isPresent(); + var partUsage = optionalPartUsage.get(); + assertFalse(partUsage.specializesFromLibrary("Occurrences::Occurrence::timeSlices")); + partUsage.setPortionKind(PortionKind.TIMESLICE); + return new ExecuteEditingContextFunctionSuccessPayload(executeEditingContextFunctionInput.id(), true); + }); + + ISemanticChecker semanticChecker = (editingContext) -> { + var optionalPartUsage = this.objectSearchService.getObject(editingContext, GeneralViewWithTopNodesTestProjectData.SemanticIds.PART_USAGE_ID) + .filter(PartUsage.class::isInstance) + .map(PartUsage.class::cast); + assertThat(optionalPartUsage).isPresent(); + var partUsage = optionalPartUsage.get(); + assertTrue(partUsage.specializesFromLibrary("Parts::Part")); + assertTrue(partUsage.specializesFromLibrary("Occurrences::Occurrence::timeSlices")); + }; + + StepVerifier.create(flux) + .then(initializeEditingContext) + .then(semanticCheckerService.checkEditingContext(semanticChecker)) + .thenCancel() + .verify(Duration.ofSeconds(10)); + } + + @DisplayName("GIVEN a snapshot Occurrence, WHEN the validation is executed, THEN the Occurrence implicitly specializes 'Occurrences::Occurrence::snapshot'") + @GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH }) + @Test + public void testImplicitTimeSliceSpecializationOnOccurrenceUsage() { + var semanticCheckerService = new SemanticCheckerService(this.semanticRunnableFactory, this.objectSearchService, GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID, + GeneralViewWithTopNodesTestProjectData.SemanticIds.PACKAGE_1_ID); + var editingContextEventInput = new EditingContextEventInput(UUID.randomUUID(), GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID); + var flux = this.editingContextEventSubscriptionRunner.run(editingContextEventInput).flux(); + + var initializeEditingContext = this.semanticRunnableFactory.createRunnable(GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID, (editingContext, executeEditingContextFunctionInput) -> { + var optionalOccurrenceUsage = this.objectSearchService.getObject(editingContext, GeneralViewWithTopNodesTestProjectData.SemanticIds.OCCURRENCE_USAGE_ID) + .filter(OccurrenceUsage.class::isInstance) + .map(OccurrenceUsage.class::cast); + assertThat(optionalOccurrenceUsage).isPresent(); + var occurrenceUsage = optionalOccurrenceUsage.get(); + assertTrue(occurrenceUsage.specializesFromLibrary("Occurrences::occurrences")); + assertFalse(occurrenceUsage.specializesFromLibrary("Occurrences::Occurrence::snapshots")); + occurrenceUsage.setPortionKind(PortionKind.SNAPSHOT); + return new ExecuteEditingContextFunctionSuccessPayload(executeEditingContextFunctionInput.id(), true); + }); + + ISemanticChecker semanticChecker = (editingContext) -> { + var optionalOccurrenceUsage = this.objectSearchService.getObject(editingContext, GeneralViewWithTopNodesTestProjectData.SemanticIds.OCCURRENCE_USAGE_ID) + .filter(OccurrenceUsage.class::isInstance) + .map(OccurrenceUsage.class::cast); + assertThat(optionalOccurrenceUsage).isPresent(); + var occurrenceUsage = optionalOccurrenceUsage.get(); + assertTrue(occurrenceUsage.specializesFromLibrary("Occurrences::occurrences")); + assertTrue(occurrenceUsage.specializesFromLibrary("Occurrences::Occurrence::snapshots")); + }; + + StepVerifier.create(flux) + .then(initializeEditingContext) + .then(semanticCheckerService.checkEditingContext(semanticChecker)) + .thenCancel() + .verify(Duration.ofSeconds(10)); } } diff --git a/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/helper/ImplicitSpecializationSwitch.java b/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/helper/ImplicitSpecializationSwitch.java index 227b1986e..3ab7f725b 100644 --- a/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/helper/ImplicitSpecializationSwitch.java +++ b/backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/helper/ImplicitSpecializationSwitch.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,108 @@ import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; -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.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; @@ -739,6 +840,19 @@ public List caseOccurrenceDefinition(OccurrenceDefinition object @Override public List caseOccurrenceUsage(OccurrenceUsage object) { + if (PortionKind.TIMESLICE.equals(object.getPortionKind())) { + var implicitTimeSliceSubsetting = this.implicitSubsetting(object, "Occurrences::Occurrence::timeSlices"); + if (implicitTimeSliceSubsetting != null) { + this.implicitSpecializations.add(implicitTimeSliceSubsetting); + } + } + if (PortionKind.SNAPSHOT.equals(object.getPortionKind())) { + var implicitSnapshotSubsetting = this.implicitSubsetting(object, "Occurrences::Occurrence::snapshots"); + if (implicitSnapshotSubsetting != null) { + this.implicitSpecializations.add(implicitSnapshotSubsetting); + } + } + if (!this.implicitSpecializations.hasSubSetting()) { var implicitSubsetting = this.implicitSubsetting(object, "Occurrences::occurrences"); if (implicitSubsetting != null) {