From 3d53400979f72bf461d28c9093a46896129428af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Bausson?= Date: Wed, 30 Oct 2024 15:47:47 +0100 Subject: [PATCH] [818] Support of OccurrenceDefinition & OccurrenceUsage types export. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Timeslice * Snapshot Bug: https://github.com/eclipse-syson/syson/issues/818 Signed-off-by: Étienne Bausson --- CHANGELOG.adoc | 4 ++- .../sysml/export/SysMLElementSerializer.java | 33 ++++++++++++++--- .../export/utils/SysMLKeywordSwitch.java | 14 ++++++++ .../export/SysMLElementSerializerTest.java | 36 +++++++++++++++++++ .../pages/release-notes/2025.1.0.adoc | 3 +- 5 files changed, 84 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 2214c656a..08a627896 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -22,12 +22,14 @@ - https://github.com/eclipse-syson/syson/issues/829[#829] [metamodel] `OccurrenceUsag#portionKind` is now unsettable and its default value is `null`. - https://github.com/eclipse-syson/syson/issues/796[#796] [import] Improve the code in import module, by making it more generic +- https://github.com/eclipse-syson/syson/issues/818[#818] [export] Add partial support of `OccurrenceDefinition` and 'OccurrenceUsage` in export from model to textual SysMLv2. +- https://github.com/eclipse-syson/syson/issues/829[#829] [metamodel] Changed cardinality of PortionKind on OccurrenceUsage to [0..1], now unsettable. Now default to null. +- https://github.com/eclipse-syson/syson/issues/812[#812] [export] Fix visibility issue when resolving name of privately imported element during export. === New features - https://github.com/eclipse-syson/syson/issues/802[#802] [diagrams] Handle imported package elements in diagrams. - == v2024.11.0 === Breaking changes diff --git a/backend/application/syson-sysml-export/src/main/java/org/eclipse/syson/sysml/export/SysMLElementSerializer.java b/backend/application/syson-sysml-export/src/main/java/org/eclipse/syson/sysml/export/SysMLElementSerializer.java index 89cb1d9ac..71d660839 100644 --- a/backend/application/syson-sysml-export/src/main/java/org/eclipse/syson/sysml/export/SysMLElementSerializer.java +++ b/backend/application/syson-sysml-export/src/main/java/org/eclipse/syson/sysml/export/SysMLElementSerializer.java @@ -98,6 +98,7 @@ 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; @@ -237,6 +238,11 @@ public String caseAttributeDefinition(AttributeDefinition attrDef) { return this.appendDefaultDefinition(this.newAppender(), attrDef).toString(); } + @Override + public String caseOccurrenceDefinition(OccurrenceDefinition occDef) { + return this.appendDefaultDefinition(this.newAppender(), occDef).toString(); + } + @Override public String casePortDefinition(PortDefinition portDef) { return this.appendDefaultDefinition(this.newAppender(), portDef).toString(); @@ -252,6 +258,19 @@ public String casePartUsage(PartUsage partUsage) { return this.appendDefaultUsage(this.newAppender(), partUsage).toString(); } + @Override + public String caseOccurrenceUsage(OccurrenceUsage occurrenceUsage) { + String serializedDeclaration; + if (PortionKind.SNAPSHOT.equals(occurrenceUsage.getPortionKind())) { + serializedDeclaration = this.serializeDeclarationWithModifiers(this.newAppender(), occurrenceUsage, "snapshot"); + } else if (PortionKind.TIMESLICE.equals(occurrenceUsage.getPortionKind())) { + serializedDeclaration = this.serializeDeclarationWithModifiers(this.newAppender(), occurrenceUsage, "timeslice"); + } else { + serializedDeclaration = this.appendDefaultUsage(this.newAppender(), occurrenceUsage); + } + return serializedDeclaration; + } + @Override public String caseReferenceUsage(ReferenceUsage reference) { Appender builder = new Appender(this.lineSeparator, this.indentation); @@ -473,10 +492,14 @@ public String caseLiteralInteger(LiteralInteger literal) { } private String appendDefaultUsage(Appender builder, Usage usage) { + return this.serializeDeclarationWithModifiers(builder, usage, this.getUsageKeyword(usage)); + } + + private String serializeDeclarationWithModifiers(Appender builder, Usage usage, String keyword) { this.appendUsagePrefix(builder, usage); - builder.appendSpaceIfNeeded().append(this.getUsageKeyword(usage)); + builder.appendSpaceIfNeeded().append(keyword); this.appendUsageDeclaration(builder, usage); @@ -1508,7 +1531,7 @@ private void appendUsagePrefix(Appender builder, Usage usage) { this.appendBasicUsagePrefix(builder, usage); final String isRef; - if (usage.isIsReference() && !this.isImplicitlyReferencial(usage)) { + if (usage.isIsReference() && !this.isImplicitlyReferential(usage)) { isRef = "ref"; } else { isRef = ""; @@ -1533,8 +1556,10 @@ private void appendOccurrenceUsagePrefix(Appender builder, OccurrenceUsage occUs this.appendExtensionKeyword(builder, occUsage); } - private boolean isImplicitlyReferencial(Usage usage) { - return usage instanceof AttributeUsage || usage instanceof ReferenceUsage || usage.getOwningMembership() instanceof ActorMembership; + private boolean isImplicitlyReferential(Usage usage) { + return usage.getOwningMembership() instanceof ActorMembership + || usage instanceof AttributeUsage + || usage instanceof ReferenceUsage; } private void appendExtensionKeyword(Appender builder, Type type) { diff --git a/backend/application/syson-sysml-export/src/main/java/org/eclipse/syson/sysml/export/utils/SysMLKeywordSwitch.java b/backend/application/syson-sysml-export/src/main/java/org/eclipse/syson/sysml/export/utils/SysMLKeywordSwitch.java index 3f9a3114f..89f9f2f8f 100644 --- a/backend/application/syson-sysml-export/src/main/java/org/eclipse/syson/sysml/export/utils/SysMLKeywordSwitch.java +++ b/backend/application/syson-sysml-export/src/main/java/org/eclipse/syson/sysml/export/utils/SysMLKeywordSwitch.java @@ -28,6 +28,8 @@ import org.eclipse.syson.sysml.InterfaceUsage; import org.eclipse.syson.sysml.ItemDefinition; import org.eclipse.syson.sysml.ItemUsage; +import org.eclipse.syson.sysml.OccurrenceDefinition; +import org.eclipse.syson.sysml.OccurrenceUsage; import org.eclipse.syson.sysml.PartDefinition; import org.eclipse.syson.sysml.PartUsage; import org.eclipse.syson.sysml.PerformActionUsage; @@ -61,6 +63,8 @@ public class SysMLKeywordSwitch extends SysmlSwitch { private static final String ITEM_KEYWORD = "item"; + private static final String OCCURRENCE_KEYWORD = "occurrence"; + private static final String ENUM_KEYWORD = "enum"; private static final String ATTRIBUTE_KEYWORD = "attribute"; @@ -135,6 +139,16 @@ public String caseItemUsage(ItemUsage object) { return ITEM_KEYWORD; } + @Override + public String caseOccurrenceDefinition(OccurrenceDefinition object) { + return OCCURRENCE_KEYWORD; + } + + @Override + public String caseOccurrenceUsage(OccurrenceUsage object) { + return OCCURRENCE_KEYWORD; + } + @Override public String caseInterfaceDefinition(InterfaceDefinition object) { return INTERFACE_KEYWORD; diff --git a/backend/application/syson-sysml-export/src/test/java/org/eclipse/syson/sysml/export/SysMLElementSerializerTest.java b/backend/application/syson-sysml-export/src/test/java/org/eclipse/syson/sysml/export/SysMLElementSerializerTest.java index 3badbfa2f..b7aeb5992 100644 --- a/backend/application/syson-sysml-export/src/test/java/org/eclipse/syson/sysml/export/SysMLElementSerializerTest.java +++ b/backend/application/syson-sysml-export/src/test/java/org/eclipse/syson/sysml/export/SysMLElementSerializerTest.java @@ -55,6 +55,7 @@ import org.eclipse.syson.sysml.Namespace; import org.eclipse.syson.sysml.NamespaceImport; 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; @@ -66,6 +67,7 @@ import org.eclipse.syson.sysml.PortConjugation; 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; @@ -122,6 +124,8 @@ public class SysMLElementSerializerTest { private static final String ANNOTATING1 = "Annotating1"; + private static final String OCCURRENCE1 = "occurrence1"; + private static final String BODY = "A body"; private ModelBuilder builder; @@ -360,6 +364,11 @@ public void interfaceDefinition() { this.checkBasicDefinitionDeclaration(InterfaceDefinition.class, "interface def"); } + @Test + public void occurrenceDefinition() { + this.checkBasicDefinitionDeclaration(OccurrenceDefinition.class, "occurrence def"); + } + private void checkBasicDefinitionDeclaration(Class type, String keyword) { Package p1 = this.builder.createWithName(Package.class, PACKAGE1); @@ -1588,4 +1597,31 @@ public void itemUsage() { } }""", model.getItemTest()); } + + @Test + public void occurrenceUsage() { + OccurrenceUsage occurrenceUsage = this.builder.createWithName(OccurrenceUsage.class, OCCURRENCE1); + occurrenceUsage.setIsComposite(true); + + this.assertTextualFormEquals("occurrence occurrence1;", occurrenceUsage); + } + + @Test + public void occurrenceUsageAsSnapshot() { + OccurrenceUsage occurrenceUsage = this.builder.createWithName(OccurrenceUsage.class, OCCURRENCE1); + occurrenceUsage.setIsComposite(true); + occurrenceUsage.setPortionKind(PortionKind.SNAPSHOT); + + this.assertTextualFormEquals("snapshot occurrence1;", occurrenceUsage); + } + + @Test + public void occurrenceUsageAsTimeslice() { + OccurrenceUsage occurrenceUsage = this.builder.createWithName(OccurrenceUsage.class, OCCURRENCE1); + occurrenceUsage.setIsComposite(true); + occurrenceUsage.setPortionKind(PortionKind.TIMESLICE); + + this.assertTextualFormEquals("timeslice occurrence1;", occurrenceUsage); + } + } diff --git a/doc/content/modules/user-manual/pages/release-notes/2025.1.0.adoc b/doc/content/modules/user-manual/pages/release-notes/2025.1.0.adoc index b0ba10e3f..437fb805a 100644 --- a/doc/content/modules/user-manual/pages/release-notes/2025.1.0.adoc +++ b/doc/content/modules/user-manual/pages/release-notes/2025.1.0.adoc @@ -12,9 +12,10 @@ - `OccurrenceUsage#portionKind` is now `unsettable` and its default value is `null` in the SysMLv2 metamodel to conform to the specification. - Improve the code in import module, by making it more generic. It now reports (on the server side) more messages to understand the scope of what is imported and the errors encountered. +- Add support of `OccurrenceDefinition` and 'OccurrenceUsage` in export from model to textual SysMLv2. == New features - Handle imported package elements in diagrams. -image::namesapce-import.png[Namespace import node] \ No newline at end of file +image::namesapce-import.png[Namespace import node]