Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ It is now _Become nested Concern_ instead of _Become nested Requirement_.
Following KerML, where `endFeature` is defined as the owned features having `isEnd = true`, the ends owned through a plain `FeatureMembership` are now collected as well, and not only those owned through an `EndFeatureMembership`.
This also fixes `relatedFeature`, `sourceFeature` and `targetFeature`, which were all empty for such connections.
- https://github.com/eclipse-syson/syson/issues/2226[#2226] [import] Fix textual import of annotations on relationships so their `annotatedElement` is set and they are returned by `Element#getOwnedAnnotation()`.
- https://github.com/eclipse-syson/syson/issues/2419[#2419] [export] Fix the export of the prefix metadata carried by the ends of a connector, which were dropped when those ends are declared inline.
The ends of a connector created from a diagram are owned through an `EndFeatureMembership` and are exported inline, so their metadata, such as the `#original` and `#derive` of a requirement derivation, were lost.

=== Improvements

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1680,6 +1680,51 @@ public void interfaceUsageWithNestedPortEnd() {
this.assertTextualFormEquals("connection interface1 connect livingRoom.heater.socket to outlet;", interfaceUsage);
}

@Test
public void connectionUsageWithMetadataOnItsEnds() {
PartUsage rootPart = this.builder.createWithName(PartUsage.class, "owner1");

PortUsage socket = this.builder.createInWithName(PortUsage.class, rootPart, "socket");
PortUsage outlet = this.builder.createInWithName(PortUsage.class, rootPart, "outlet");

InterfaceUsage interfaceUsage = this.builder.createWithName(InterfaceUsage.class, "interface1");
this.addAsFeatureMember(rootPart, interfaceUsage);

EndFeatureMembership sourceEnd = this.createConnectionEndFeatureMembership(socket);
this.applyMetadataOnEnd(sourceEnd, "original");
EndFeatureMembership targetEnd = this.createConnectionEndFeatureMembership(outlet);
this.applyMetadataOnEnd(targetEnd, "derive");
interfaceUsage.getOwnedRelationship().add(sourceEnd);
interfaceUsage.getOwnedRelationship().add(targetEnd);

this.assertTextualFormEquals("connection interface1 connect #original socket to #derive outlet;", interfaceUsage);
}

/**
* Applies a prefix metadata on the end owned by the given membership, the way {@code #original} and {@code #derive}
* are applied on the ends of a requirement derivation.
*/
private void applyMetadataOnEnd(EndFeatureMembership endFeatureMembership, String metadataDefinitionName) {
MetadataDefinition metadataDefinition = this.fact.createMetadataDefinition();
metadataDefinition.setDeclaredName(metadataDefinitionName);

MetadataUsage metadataUsage = this.fact.createMetadataUsage();
OwningMembership owningMembership = this.fact.createOwningMembership();
owningMembership.getOwnedRelatedElement().add(metadataUsage);
owningMembership.setMemberElement(metadataUsage);

FeatureTyping featureTyping = this.fact.createFeatureTyping();
featureTyping.setType(metadataDefinition);
featureTyping.setTypedFeature(metadataUsage);
metadataUsage.getOwnedRelationship().add(featureTyping);

endFeatureMembership.getOwnedRelatedElement().stream()
.filter(Feature.class::isInstance)
.map(Feature.class::cast)
.findFirst()
.ifPresent(endFeature -> endFeature.getOwnedRelationship().add(owningMembership));
}

@Test
public void interfaceUsageWithUnresolvedPortEnd() {
PartUsage rootPart = this.builder.createWithName(PartUsage.class, "part1");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1743,6 +1743,9 @@ private void appendConnectorEndMember(Appender builder, EndFeatureMembership end
}

private void appendConnectorEnd(Appender builder, Feature endFeature) {
// Prefix metadata of the end, such as the #original and #derive of a requirement derivation. Without this the
// metadata of an end owned through an EndFeatureMembership would be dropped by the export.
this.appendExtensionKeyword(builder, endFeature);

// Handle ownedRelationship += OwnedMultiplicity
endFeature.getOwnedRelationship().stream().filter(OwningMembership.class::isInstance)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ Those connections were missing their source and their target, and were therefore
** Fix expression creation and editing on `SuccessionAsUsage` elements.
** Fix the _Typed by_ property in the _Details_ view so a `Usage` can only be typed by its corresponding `Definition` kind.

* In textual import/export:

** Fix the export of the keywords carried by the ends of a connection, such as the `#original` and `#derive` of a requirement derivation, which were missing from the exported text when the connection had been created from a diagram.
Exporting such a connection and importing it back no longer loses which end is which.

== Improvements

* In diagrams:
Expand Down
Loading