Skip to content
Draft
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
5 changes: 3 additions & 2 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@

- https://github.com/eclipse-syson/syson/issues/2198[#2198] [diagrams] Improve diagram-to-diagram drag and drop to support dropping multiple graphical nodes at once, leveraging Sirius Web's `droppedNodes` and `droppedElements` variables.
- https://github.com/eclipse-syson/syson/issues/2194[#2194] [diagrams] Properly report feedback messages to user when using _ISysMLMoveElementService_.
- https://github.com/eclipse-syson/syson/issues/2182[#2182] [services] Provide a way for downstream applications to extend _ISysMLMoveElementService_;
- https://github.com/eclipse-syson/syson/issues/2182[#2182] [services] Provide a way for downstream applications to extend _ISysMLMoveElementService_.
- https://github.com/eclipse-syson/syson/issues/2240[#2240] [diagrams] Update the choice of _timeslice_ and _snapshot_ elements that can be created in the selection dialog of tools creating _timeslice_ and _snapshot_ elements.
Before, the selection dialog option with selection allowed choosing between all _timeslice/snapshot_ types.
Now, the choice is restricted to the _timeslice/snapshot_ type that match the graphical node type on which the tool is applied.

- https://github.com/eclipse-syson/syson/issues/2119[#2119] [details] Display expressions values in the _Details_ view and allow to edit them from there.
- https://github.com/eclipse-syson/syson/issues/2251[#2251] [explorer] Allow expression-related operations on their parent element

=== New features

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@
@Configuration
public class SysMLv2PropertiesConfigurer implements IPropertiesDescriptionRegistryConfigurer {

private static final String CUSTOM_EXPRESSION_WIDGET_KEY = "syson:expression-value-widget";

private static final String CORE_PROPERTIES = "Core Properties";

private static final String ADVANCED_PROPERTIES = "Advanced Properties";
Expand Down Expand Up @@ -189,6 +191,8 @@ private FormDescription createDetailsViewForElement() {
pageCore.getGroups().add(this.createExtraAcceptActionUsagePropertiesGroup());
pageCore.getGroups().add(this.createExtraTransitionSourceTargetPropertiesGroup());
pageCore.getGroups().add(this.createFeatureValuePropertiesGroup());
pageCore.getGroups().add(this.createExpressionPropertiesGroup());
pageCore.getGroups().add(this.createResultExpressionPropertiesGroup());

PageDescription pageAdvanced = FormFactory.eINSTANCE.createPageDescription();
pageAdvanced.setName("SysON-DetailsView-Advanced");
Expand All @@ -203,6 +207,28 @@ private FormDescription createDetailsViewForElement() {
return form;
}

/**
* Creates a group to display the value of an Expression.
*
* @return a {@link GroupDescription}
*/
private GroupDescription createExpressionPropertiesGroup() {
GroupDescription group = FormFactory.eINSTANCE.createGroupDescription();
group.setDisplayMode(GroupDisplayMode.LIST);
group.setName("Expression Value");
group.setLabelExpression("");
group.setSemanticCandidatesExpression(ServiceMethod.of0(DetailsViewService::getExpression).aqlSelf());

TextAreaDescription expressionWidget = FormFactory.eINSTANCE.createTextAreaDescription();
expressionWidget.setName("Expression");
expressionWidget.setLabelExpression(CUSTOM_EXPRESSION_WIDGET_KEY);
expressionWidget.setValueExpression(ServiceMethod.of0(DetailsViewService::getExpressionTextualRepresentation).aqlSelf());
expressionWidget.setIsEnabledExpression(AQLConstants.AQL_FALSE);

group.getChildren().add(expressionWidget);

return group;
}

/**
* Creates a group to display the value of a Feature or FeatureValue.
Expand All @@ -218,7 +244,7 @@ private GroupDescription createFeatureValuePropertiesGroup() {

TextAreaDescription expressionWidget = FormFactory.eINSTANCE.createTextAreaDescription();
expressionWidget.setName("ValueExpression");
expressionWidget.setLabelExpression("Value");
expressionWidget.setLabelExpression(CUSTOM_EXPRESSION_WIDGET_KEY);
expressionWidget.setValueExpression(ServiceMethod.of0(DetailsViewService::getValueExpressionTextualRepresentation).aqlSelf());
expressionWidget.setIsEnabledExpression(AQLConstants.AQL_FALSE);

Expand All @@ -227,6 +253,29 @@ private GroupDescription createFeatureValuePropertiesGroup() {
return group;
}

/**
* Creates a group to display the value of a ResultExpression.
*
* @return a {@link GroupDescription}
*/
private GroupDescription createResultExpressionPropertiesGroup() {
GroupDescription group = FormFactory.eINSTANCE.createGroupDescription();
group.setDisplayMode(GroupDisplayMode.LIST);
group.setName("Result");
group.setLabelExpression("");
group.setSemanticCandidatesExpression(ServiceMethod.of0(DetailsViewService::getResultExpression).aqlSelf());

TextAreaDescription expressionWidget = FormFactory.eINSTANCE.createTextAreaDescription();
expressionWidget.setName("ResultExpression");
expressionWidget.setLabelExpression(CUSTOM_EXPRESSION_WIDGET_KEY);
expressionWidget.setValueExpression(ServiceMethod.of0(DetailsViewService::getResultExpressionTextualRepresentation).aqlSelf());
expressionWidget.setIsEnabledExpression(AQLConstants.AQL_FALSE);

group.getChildren().add(expressionWidget);

return group;
}

private GroupDescription createCorePropertiesGroup() {
GroupDescription group = FormFactory.eINSTANCE.createGroupDescription();
group.setDisplayMode(GroupDisplayMode.LIST);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.eclipse.sirius.components.core.api.IPayload;
import org.eclipse.syson.application.expressions.dto.ExpressionTextualRepresentationInput;
import org.eclipse.syson.application.expressions.dto.ExpressionTextualRepresentationPayload;
import org.eclipse.syson.sysml.Element;
import org.eclipse.syson.sysml.Expression;
import org.eclipse.syson.sysml.metamodel.services.MetamodelQueryElementService;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -55,14 +56,38 @@ public boolean canHandle(IEditingContext editingContext, IInput input) {
public void handle(Sinks.One<IPayload> payloadSink, Sinks.Many<ChangeDescription> changeDescriptionSink, IEditingContext editingContext, IInput input) {
String textualRepresentation = "";
if (input instanceof ExpressionTextualRepresentationInput expressionTextualRepresentationInput) {
Optional<Expression> optionalExpression = this.objectSearchService.getObject(editingContext, expressionTextualRepresentationInput.elementId())
.filter(Expression.class::isInstance)
.map(Expression.class::cast)
.filter(this.metamodelQueryElementService::isTopLevelExpression);
String elementId = expressionTextualRepresentationInput.elementId();
Optional<Expression> optionalExpression = this.getExpression(editingContext, elementId);
if (optionalExpression.isPresent()) {
textualRepresentation = this.metamodelQueryElementService.getExpressionTextualRepresentation(optionalExpression.get());
}
}
payloadSink.tryEmitValue(new ExpressionTextualRepresentationPayload(input.id(), textualRepresentation));
}

/**
* Finds the {@link Expression} element to consider given the provided {@code elementId}.
*
* @param editingContext
* the editing context.
* @param elementId
* either to id of an actual {@link Expression} element, or of the parent {@link Element} of a single
* {@code Expression}.
* @return the directly of indirectly designated {@link Expression}.
*/
private Optional<Expression> getExpression(IEditingContext editingContext, String elementId) {
Optional<Expression> result = Optional.empty();
Optional<Element> optionalElement = this.objectSearchService.getObject(editingContext, elementId)
.filter(Element.class::isInstance)
.map(Element.class::cast);
if (optionalElement.isPresent()) {
Element element = optionalElement.get();
if (element instanceof Expression expression && this.metamodelQueryElementService.isTopLevelExpression(expression)) {
result = optionalElement.map(Expression.class::cast);
} else {
result = this.metamodelQueryElementService.findSingleExpressionDefinition(element);
}
}
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import org.eclipse.syson.sysml.Annotation;
import org.eclipse.syson.sysml.Comment;
import org.eclipse.syson.sysml.ConjugatedPortDefinition;
import org.eclipse.syson.sysml.Definition;
import org.eclipse.syson.sysml.Documentation;
import org.eclipse.syson.sysml.Element;
import org.eclipse.syson.sysml.EndFeatureMembership;
Expand All @@ -55,6 +56,7 @@
import org.eclipse.syson.sysml.FeatureValue;
import org.eclipse.syson.sysml.Import;
import org.eclipse.syson.sysml.Membership;
import org.eclipse.syson.sysml.Namespace;
import org.eclipse.syson.sysml.ParameterMembership;
import org.eclipse.syson.sysml.ReferenceSubsetting;
import org.eclipse.syson.sysml.ReferenceUsage;
Expand All @@ -68,6 +70,7 @@
import org.eclipse.syson.sysml.SysmlPackage;
import org.eclipse.syson.sysml.TransitionUsage;
import org.eclipse.syson.sysml.Type;
import org.eclipse.syson.sysml.Usage;
import org.eclipse.syson.sysml.ViewUsage;
import org.eclipse.syson.sysml.metamodel.services.ElementInitializerSwitch;
import org.eclipse.syson.sysml.metamodel.services.MetamodelQueryElementService;
Expand Down Expand Up @@ -570,12 +573,16 @@ public Element setNewDocumentationValue(Element self, String newValue) {
* a {@link FeatureValue} or {@link Feature}
* @return a {@link FeatureValue} or <code>null</code>
*/
public Element getFeatureValue(Element self) {
Element result = null;
public FeatureValue getFeatureValue(Element self) {
FeatureValue result = null;
if (self instanceof FeatureValue featureValue && featureValue.getValue() != null) {
result = featureValue;
} else if (self instanceof Feature feature) {
result = this.metamodelQueryElementService.getValueExpression(feature).orElse(null);
result = feature.getOwnedRelationship().stream()
.filter(FeatureValue.class::isInstance)
.map(FeatureValue.class::cast)
.findFirst()
.orElse(null);
}
return result;
}
Expand Down Expand Up @@ -626,6 +633,39 @@ private String getExpressionAsText(Expression expression) {
return this.metamodelQueryElementService.getExpressionTextualRepresentation(expression);
}

/**
* Gets the {@link ResultExpressionMembership} from a {@link Namespace} or a {@link ResultExpressionMembership}.
*
* @param self
* a {@link Namespace} or a {@link ResultExpressionMembership}.
* @return a {@link ResultExpressionMembership} or <code>null</code>
*/
public Element getResultExpression(Element self) {
Element result = null;
if (self instanceof ResultExpressionMembership expressionMembership && expressionMembership.getOwnedResultExpression() != null) {
result = expressionMembership;
} else if (self instanceof Namespace namespace && this.metamodelQueryElementService.getResultExpressionMembership(namespace) != null
&& this.metamodelQueryElementService.getResultExpressionMembership(namespace).getOwnedResultExpression() != null) {
result = this.metamodelQueryElementService.getResultExpressionMembership(namespace);
}
return result;
}

/**
* Gets the {@link ResultExpressionMembership} from a {@link Namespace} or a {@link ResultExpressionMembership}.
*
* @param self
* a {@link Namespace} or a {@link ResultExpressionMembership}.
* @return a {@link ResultExpressionMembership} or <code>null</code>
*/
public Element getExpression(Element self) {
if (self instanceof Expression && !(self instanceof Usage) && !(self instanceof Definition)) {
return self;
} else {
return null;
}
}

/**
* Returns the element that owns the visibility feature of the given element.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -553,18 +553,21 @@ public void topLevelExpressionTextualRepresentation() {
treeId.set(tree.getId());
});

// The Tank part and its attribute are not themselves expressions => ""
// The Tank part is not an expression => ""
var checkTank = this.checkExpressiontTextualRepresentation(editingContextId, ExpressionSamplesProjectData.SemanticIds.TANK_ID, "");
var checkTankAttribute = this.checkExpressiontTextualRepresentation(editingContextId, ExpressionSamplesProjectData.SemanticIds.TANK_MAX_VOLUME_ATTRIBUTE_ID, "");
// The Tank's attribute is not an expression itself either, but it owns a single, non-ambiguous expression to
// can act as a "shortcut" to interact with id.
var checkTankAttribute = this.checkExpressiontTextualRepresentation(editingContextId, ExpressionSamplesProjectData.SemanticIds.TANK_MAX_VOLUME_ATTRIBUTE_ID, "100.0 * minVolume");
// The actual attribute default value expression however should be correctly represented
var checkTankAttributeValueExpression = this.checkExpressiontTextualRepresentation(editingContextId, ExpressionSamplesProjectData.SemanticIds.TANK_MAX_VOLUME_ATTRIBUTE_VALUE_ID,
"100.0 * minVolume");

var checkPerformanceConcern = this.checkExpressiontTextualRepresentation(editingContextId, ExpressionSamplesProjectData.SemanticIds.PERFORMANCE_CONCERN_ID, "");
// A ConstaintUsage *is* an Expression from the point of view of SysML's type hierarchy, but not a top-level
// Expression, so we expect "" here.
// Expression. However if it contains a single expression, it an act as a "shortcut" to it.
var checkPerformanceConcernAssumeConstraint = this.checkExpressiontTextualRepresentation(editingContextId, ExpressionSamplesProjectData.SemanticIds.PERFORMANCE_CONCERN_ASSUME_ID, "");
var checkPerformanceConcernRequireConstraint = this.checkExpressiontTextualRepresentation(editingContextId, ExpressionSamplesProjectData.SemanticIds.PERFORMANCE_CONCERN_REQUIRE_ID, "");
var checkPerformanceConcernRequireConstraint = this.checkExpressiontTextualRepresentation(editingContextId, ExpressionSamplesProjectData.SemanticIds.PERFORMANCE_CONCERN_REQUIRE_ID,
"s.samplingRate >= 50.0 & s.currentValue != 0.0 | s.errorCount == 0");
// require s.samplingRate >= 50.0 & s.currentValue != 0.0 | s.errorCount == 0
var checkPerformanceConcernRequireConstraintExpression = this.checkExpressiontTextualRepresentation(editingContextId,
ExpressionSamplesProjectData.SemanticIds.PERFORMANCE_CONCERN_REQUIRE_EXPRESSION_ID, "s.samplingRate >= 50.0 & s.currentValue != 0.0 | s.errorCount == 0");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@
*
* @author pcdavid
*/
public record EditExpressionInput(UUID id, String editingContextId, String expressionElementId, String newExpressionText) implements IInput {
public record EditExpressionInput(UUID id, String editingContextId, String elementId, String newExpressionText) implements IInput {
}
Loading
Loading