diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 81d28a642..15cb0d1bb 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -16,6 +16,24 @@ As a result, the following GraphQL mutations have been removed `exposeRequiremen - https://github.com/eclipse-syson/syson/issues/2045[#2045] [diagrams] The service `ViewNodeService#revealCompartment` has been changed to reveal a compartment only when it is needed. + Only reveal a compartment of a node when none of the revealed compartment can display the `targetElement`. + If many compartment candidates exist, choose the first free form compartment. +- [services] As part of the migration to the new diagram service architecture, the following methods have been moved out of `ViewNodeService` (which as been deleted): ++ +** `List getExposedElements(Element self, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext)` to `DiagramQueryAQLService.getExposedElements(Element self, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext)` +** `List getExposedElements(Element self, Element parent, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext)` to `DiagramQueryAQLService.getExposedElements(Element self, Element parent, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext)` +** `boolean isView(Element self, String viewDefinition, List ancestors, IEditingContext editingContext, DiagramContext diagramContext)` to `DiagramQueryAQLService.isView(Element self, String viewDefinition, List ancestors, IEditingContext editingContext, DiagramContext diagramContext)` +** `boolean isView(Element self, String viewDefinition, Node selectedNode, IEditingContext editingContext, DiagramContext diagramContext)` to `DiagramQueryAQLService.isView(Element self, String viewDefinition, Node selectedNode, IEditingContext editingContext, DiagramContext diagramContext)` +** `boolean isHiddenByDefault(Element self, String compartmentName, List ancestors, IEditingContext editingContext, DiagramContext diagramContext)` to `DiagramQueryAQLService.isHiddenByDefault(Element self, String compartmentName, List ancestors, IEditingContext editingContext, DiagramContext diagramContext)` +** `List getExposedActors(Element self, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext)` to `DiagramQueryAQLService.getExposedActors(Element self, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext)` +** `List getExposedStakeholders(Element self, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext)` to `DiagramQueryAQLService.getExposedStakeholders(Element self, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext)` +** `List getExposedSubjects(Element self, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext)` to `DiagramQueryAQLService.getExposedSubjects(Element self, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext)` +** `List getAllReachableRequirements(EObject self)` to `DiagramQueryAQLService.getAllReachableRequirements(EObject self)` +** `boolean isAncestorOf(org.eclipse.sirius.components.representations.Element parentNodeElement, org.eclipse.sirius.components.representations.Element childNodeElement, DiagramRenderingCache cache)` to `DiagramQueryAQLService.isAncestorOf(org.eclipse.sirius.components.representations.Element parentNodeElement, org.eclipse.sirius.components.representations.Element childNodeElement, DiagramRenderingCache cache)` +** `boolean showAnnotatingNode(Element self, DiagramContext diagramContext, IEditingContext editingContext)` to `DiagramQueryAQLService.showAnnotatingNode(Element self, DiagramContext diagramContext, IEditingContext editingContext)` +** `Node revealCompartment(Node selectedNode, Element targetElement, DiagramContext diagramContext, IEditingContext editingContext, Map convertedNodes)` to `DiagramMutationAQLService.revealCompartment(Node selectedNode, Element targetElement, DiagramContext diagramContext, IEditingContext editingContext, Map convertedNodes)` +** `org.eclipse.syson.diagram.common.view.services.ViewFilterSwitch` to `org.eclipse.syson.diagram.services.utils.ViewFilterSwitch` +** `org.eclipse.syson.diagram.common.view.services.RevealCompartmentSwitch` to `org.eclipse.syson.diagram.services.utils.RevealCompartmentSwitch` ++ +Also, a new helper method `DiagramQueryAQLService.isNotAncestorOf(...)` has been added to support edge preconditions previously written as `aql:not graphicalEdgeSource.isAncestorOf(graphicalEdgeTarget, cache)`. === Dependency update diff --git a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/configuration/SysMLv2PropertiesConfigurer.java b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/configuration/SysMLv2PropertiesConfigurer.java index a39f3d915..4384dcac1 100644 --- a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/configuration/SysMLv2PropertiesConfigurer.java +++ b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/configuration/SysMLv2PropertiesConfigurer.java @@ -17,10 +17,15 @@ import java.util.Objects; import java.util.UUID; +import org.eclipse.acceleo.query.services.EObjectServices; import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl; +import org.eclipse.syson.sysml.Element; import org.eclipse.emf.edit.provider.ComposedAdapterFactory.Descriptor; import org.eclipse.sirius.components.collaborative.forms.services.api.IPropertiesDescriptionRegistry; import org.eclipse.sirius.components.collaborative.forms.services.api.IPropertiesDescriptionRegistryConfigurer; @@ -60,7 +65,6 @@ import org.eclipse.syson.model.services.aql.ModelQueryAQLService; import org.eclipse.syson.services.UtilService; import org.eclipse.syson.sysml.SysmlPackage; -import org.eclipse.syson.sysml.helper.LabelConstants; import org.eclipse.syson.util.AQLConstants; import org.eclipse.syson.util.AQLUtils; import org.eclipse.syson.util.ServiceMethod; @@ -140,7 +144,7 @@ public void addPropertiesDescriptions(IPropertiesDescriptionRegistry registry) { // The FormDescription must be part of View inside a proper EMF Resource to be correctly handled URI uri = URI.createURI(IEMFEditingContext.RESOURCE_SCHEME + ":///" + UUID.nameUUIDFromBytes(SysMLv2PropertiesConfigurer.class.getCanonicalName().getBytes())); Resource resource = new XMIResourceImpl(uri); - View view = org.eclipse.sirius.components.view.ViewFactory.eINSTANCE.createView(); + View view = ViewFactory.eINSTANCE.createView(); view.eAllContents().forEachRemaining(eObject -> { eObject.eAdapters().add(new IDAdapter(UUID.nameUUIDFromBytes(EcoreUtil.getURI(eObject).toString().getBytes()))); @@ -263,8 +267,8 @@ private GroupDescription createExtraRedefinitionPropertiesGroup() { refWidget.setReferenceOwnerExpression(AQLConstants.AQL_SELF); refWidget.setIsEnabledExpression(AQL_NOT_SELF_IS_READ_ONLY); ChangeContext setRefWidget = ViewFactory.eINSTANCE.createChangeContext(); - setRefWidget.setExpression("aql:self.handleReferenceWidgetNewValue('" + SysmlPackage.eINSTANCE.getRedefinition_RedefinedFeature().getName() + "', " + ViewFormDescriptionConverter.NEW_VALUE - + LabelConstants.CLOSE_PARENTHESIS); + setRefWidget.setExpression(ServiceMethod.of2(DetailsViewService::handleReferenceWidgetNewValue) + .aqlSelf(AQLUtils.aqlString(SysmlPackage.eINSTANCE.getRedefinition_RedefinedFeature().getName()), ViewFormDescriptionConverter.NEW_VALUE)); refWidget.getBody().add(setRefWidget); group.getChildren().add(refWidget); @@ -287,9 +291,8 @@ private GroupDescription createExtraReferenceSubsettingPropertiesGroup() { refWidget.setReferenceOwnerExpression(AQLConstants.AQL_SELF); refWidget.setIsEnabledExpression(AQL_NOT_SELF_IS_READ_ONLY); ChangeContext setRefWidget = ViewFactory.eINSTANCE.createChangeContext(); - setRefWidget - .setExpression("aql:self.handleReferenceWidgetNewValue('" + SysmlPackage.eINSTANCE.getReferenceSubsetting_ReferencedFeature().getName() + "', " + ViewFormDescriptionConverter.NEW_VALUE - + LabelConstants.CLOSE_PARENTHESIS); + setRefWidget.setExpression(ServiceMethod.of2(DetailsViewService::handleReferenceWidgetNewValue) + .aqlSelf(AQLUtils.aqlString(SysmlPackage.eINSTANCE.getReferenceSubsetting_ReferencedFeature().getName()), ViewFormDescriptionConverter.NEW_VALUE)); refWidget.getBody().add(setRefWidget); group.getChildren().add(refWidget); @@ -307,14 +310,15 @@ private GroupDescription createExtraStatesubactionMembershipKindPropertiesGroup( RadioDescription radio = FormFactory.eINSTANCE.createRadioDescription(); radio.setName("ExtraRadioKindWidget"); radio.setLabelExpression("Kind"); - radio.setCandidatesExpression(AQLUtils.getSelfServiceCallExpression("getEnumCandidates", AQLUtils.aqlString(SysmlPackage.eINSTANCE.getStateSubactionMembership_Kind().getName()))); + radio.setCandidatesExpression(ServiceMethod.of1(DetailsViewService.class, DetailsViewService::getEnumCandidates, Element.class, String.class) + .aqlSelf(AQLUtils.aqlString(SysmlPackage.eINSTANCE.getStateSubactionMembership_Kind().getName()))); radio.setCandidateLabelExpression("aql:candidate.name"); - radio.setValueExpression(AQLUtils.getSelfServiceCallExpression("getEnumValue", AQLUtils.aqlString(SysmlPackage.eINSTANCE.getStateSubactionMembership_Kind().getName()))); + radio.setValueExpression(ServiceMethod.of1(DetailsViewService.class, DetailsViewService::getEnumValue, Element.class, String.class) + .aqlSelf(AQLUtils.aqlString(SysmlPackage.eINSTANCE.getStateSubactionMembership_Kind().getName()))); radio.setIsEnabledExpression(AQL_NOT_SELF_IS_READ_ONLY); ChangeContext setNewValueOperation = ViewFactory.eINSTANCE.createChangeContext(); - setNewValueOperation - .setExpression( - AQLUtils.getSelfServiceCallExpression("setNewValue", List.of(AQLUtils.aqlString(SysmlPackage.eINSTANCE.getStateSubactionMembership_Kind().getName()), "newValue.instance"))); + setNewValueOperation.setExpression(ServiceMethod.of2(DetailsViewService.class, DetailsViewService::setNewValue, Element.class, String.class, Object.class) + .aqlSelf(AQLUtils.aqlString(SysmlPackage.eINSTANCE.getStateSubactionMembership_Kind().getName()), "newValue.instance")); radio.getBody().add(setNewValueOperation); group.getChildren().add(radio); @@ -337,8 +341,8 @@ private GroupDescription createExtraSubclassificationPropertiesGroup() { refWidget.setReferenceOwnerExpression(AQLConstants.AQL_SELF); refWidget.setIsEnabledExpression(AQL_NOT_SELF_IS_READ_ONLY); ChangeContext setRefWidget = ViewFactory.eINSTANCE.createChangeContext(); - setRefWidget.setExpression("aql:self.handleReferenceWidgetNewValue('" + SysmlPackage.eINSTANCE.getSubclassification_Superclassifier().getName() + "', " + ViewFormDescriptionConverter.NEW_VALUE - + LabelConstants.CLOSE_PARENTHESIS); + setRefWidget.setExpression(ServiceMethod.of2(DetailsViewService::handleReferenceWidgetNewValue) + .aqlSelf(AQLUtils.aqlString(SysmlPackage.eINSTANCE.getSubclassification_Superclassifier().getName()), ViewFormDescriptionConverter.NEW_VALUE)); refWidget.getBody().add(setRefWidget); group.getChildren().add(refWidget); @@ -361,8 +365,8 @@ private GroupDescription createExtraSubsettingPropertiesGroup() { refWidget.setReferenceOwnerExpression(AQLConstants.AQL_SELF); refWidget.setIsEnabledExpression(AQL_NOT_SELF_IS_READ_ONLY); ChangeContext setRefWidget = ViewFactory.eINSTANCE.createChangeContext(); - setRefWidget.setExpression("aql:self.handleReferenceWidgetNewValue('" + SysmlPackage.eINSTANCE.getSubsetting_SubsettedFeature().getName() + "', " + ViewFormDescriptionConverter.NEW_VALUE - + LabelConstants.CLOSE_PARENTHESIS); + setRefWidget.setExpression(ServiceMethod.of2(DetailsViewService::handleReferenceWidgetNewValue) + .aqlSelf(AQLUtils.aqlString(SysmlPackage.eINSTANCE.getSubsetting_SubsettedFeature().getName()), ViewFormDescriptionConverter.NEW_VALUE)); refWidget.getBody().add(setRefWidget); group.getChildren().add(refWidget); @@ -580,7 +584,7 @@ private WidgetDescription createLabelWidget() { label.setName("LabelWidget"); label.setLabelExpression(ServiceMethod.of1(DetailsViewService::getDetailsViewLabel).aqlSelf(E_STRUCTURAL_FEATURE)); label.setHelpExpression(ServiceMethod.of1(DetailsViewService::getDetailsViewHelpText).aqlSelf(E_STRUCTURAL_FEATURE)); - label.setValueExpression(AQLUtils.getSelfServiceCallExpression("eGet", E_STRUCTURAL_FEATURE)); + label.setValueExpression(ServiceMethod.of1(EObjectServices.class, EObjectServices::eGet, EObject.class, EStructuralFeature.class).aqlSelf(E_STRUCTURAL_FEATURE)); return label; } @@ -589,10 +593,11 @@ private WidgetDescription createTextAreaFieldWidget() { textArea.setName("TextAreaWidget"); textArea.setLabelExpression(ServiceMethod.of1(DetailsViewService::getDetailsViewLabel).aqlSelf(E_STRUCTURAL_FEATURE)); textArea.setHelpExpression(ServiceMethod.of1(DetailsViewService::getDetailsViewHelpText).aqlSelf(E_STRUCTURAL_FEATURE)); - textArea.setValueExpression(AQLUtils.getSelfServiceCallExpression("eGet", E_STRUCTURAL_FEATURE)); + textArea.setValueExpression(ServiceMethod.of1(EObjectServices.class, EObjectServices::eGet, EObject.class, EStructuralFeature.class).aqlSelf(E_STRUCTURAL_FEATURE)); textArea.setIsEnabledExpression(AQL_NOT_SELF_IS_READ_ONLY_E_STRUCTURAL_FEATURE); ChangeContext setNewValueOperation = ViewFactory.eINSTANCE.createChangeContext(); - setNewValueOperation.setExpression(AQLUtils.getSelfServiceCallExpression("setNewValue", List.of(E_STRUCTURAL_FEATURE, ViewFormDescriptionConverter.NEW_VALUE))); + setNewValueOperation.setExpression(ServiceMethod.of2(DetailsViewService.class, DetailsViewService::setNewValue, Element.class, EStructuralFeature.class, Object.class) + .aqlSelf(E_STRUCTURAL_FEATURE, ViewFormDescriptionConverter.NEW_VALUE)); textArea.getBody().add(setNewValueOperation); return textArea; } @@ -602,10 +607,11 @@ private WidgetDescription createTextfieldWidget() { textfield.setName("TextfieldWidget"); textfield.setLabelExpression(ServiceMethod.of1(DetailsViewService::getDetailsViewLabel).aqlSelf(E_STRUCTURAL_FEATURE)); textfield.setHelpExpression(ServiceMethod.of1(DetailsViewService::getDetailsViewHelpText).aqlSelf(E_STRUCTURAL_FEATURE)); - textfield.setValueExpression(AQLUtils.getSelfServiceCallExpression("eGet", E_STRUCTURAL_FEATURE)); + textfield.setValueExpression(ServiceMethod.of1(EObjectServices.class, EObjectServices::eGet, EObject.class, EStructuralFeature.class).aqlSelf(E_STRUCTURAL_FEATURE)); textfield.setIsEnabledExpression(AQL_NOT_SELF_IS_READ_ONLY_E_STRUCTURAL_FEATURE); ChangeContext setNewValueOperation = ViewFactory.eINSTANCE.createChangeContext(); - setNewValueOperation.setExpression(AQLUtils.getSelfServiceCallExpression("setNewValue", List.of(E_STRUCTURAL_FEATURE, ViewFormDescriptionConverter.NEW_VALUE))); + setNewValueOperation.setExpression(ServiceMethod.of2(DetailsViewService.class, DetailsViewService::setNewValue, Element.class, EStructuralFeature.class, Object.class) + .aqlSelf(E_STRUCTURAL_FEATURE, ViewFormDescriptionConverter.NEW_VALUE)); textfield.getBody().add(setNewValueOperation); return textfield; } @@ -614,11 +620,12 @@ private WidgetDescription createCheckboxWidget() { CheckboxDescription checkbox = FormFactory.eINSTANCE.createCheckboxDescription(); checkbox.setName("CheckboxWidget"); checkbox.setLabelExpression(ServiceMethod.of1(DetailsViewService::getDetailsViewLabel).aqlSelf(E_STRUCTURAL_FEATURE)); - checkbox.setValueExpression(AQLUtils.getSelfServiceCallExpression("eGet", E_STRUCTURAL_FEATURE)); + checkbox.setValueExpression(ServiceMethod.of1(EObjectServices.class, EObjectServices::eGet, EObject.class, EStructuralFeature.class).aqlSelf(E_STRUCTURAL_FEATURE)); checkbox.setHelpExpression(ServiceMethod.of1(DetailsViewService::getDetailsViewHelpText).aqlSelf(E_STRUCTURAL_FEATURE)); checkbox.setIsEnabledExpression(AQL_NOT_SELF_IS_READ_ONLY_E_STRUCTURAL_FEATURE); ChangeContext setNewValueOperation = ViewFactory.eINSTANCE.createChangeContext(); - setNewValueOperation.setExpression(AQLUtils.getSelfServiceCallExpression("setNewValue", List.of(E_STRUCTURAL_FEATURE, ViewFormDescriptionConverter.NEW_VALUE))); + setNewValueOperation.setExpression(ServiceMethod.of2(DetailsViewService.class, DetailsViewService::setNewValue, Element.class, EStructuralFeature.class, Object.class) + .aqlSelf(E_STRUCTURAL_FEATURE, ViewFormDescriptionConverter.NEW_VALUE)); checkbox.getBody().add(setNewValueOperation); return checkbox; } @@ -628,12 +635,13 @@ private WidgetDescription createRadioWidget() { radio.setName("RadioWidget"); radio.setLabelExpression(ServiceMethod.of1(DetailsViewService::getDetailsViewLabel).aqlSelf(E_STRUCTURAL_FEATURE)); radio.setHelpExpression(ServiceMethod.of1(DetailsViewService::getDetailsViewHelpText).aqlSelf(E_STRUCTURAL_FEATURE)); - radio.setCandidatesExpression(AQLUtils.getSelfServiceCallExpression("getEnumCandidates", E_STRUCTURAL_FEATURE)); + radio.setCandidatesExpression(ServiceMethod.of1(DetailsViewService.class, DetailsViewService::getEnumCandidates, Element.class, EAttribute.class).aqlSelf(E_STRUCTURAL_FEATURE)); radio.setCandidateLabelExpression("aql:candidate.name"); - radio.setValueExpression(AQLUtils.getSelfServiceCallExpression("getEnumValue", E_STRUCTURAL_FEATURE)); + radio.setValueExpression(ServiceMethod.of1(DetailsViewService.class, DetailsViewService::getEnumValue, Element.class, EAttribute.class).aqlSelf(E_STRUCTURAL_FEATURE)); radio.setIsEnabledExpression(AQL_NOT_SELF_IS_READ_ONLY_E_STRUCTURAL_FEATURE); ChangeContext setNewValueOperation = ViewFactory.eINSTANCE.createChangeContext(); - setNewValueOperation.setExpression(AQLUtils.getSelfServiceCallExpression("setNewValue", List.of(E_STRUCTURAL_FEATURE, "newValue.instance"))); + setNewValueOperation.setExpression( + ServiceMethod.of2(DetailsViewService.class, DetailsViewService::setNewValue, Element.class, EStructuralFeature.class, Object.class).aqlSelf(E_STRUCTURAL_FEATURE, "newValue.instance")); radio.getBody().add(setNewValueOperation); return radio; } @@ -647,7 +655,7 @@ private WidgetDescription createReferenceWidget() { refWidget.setReferenceOwnerExpression(AQLConstants.AQL_SELF); refWidget.setIsEnabledExpression(AQL_NOT_SELF_IS_READ_ONLY_E_STRUCTURAL_FEATURE); ChangeContext setRefWidget = ViewFactory.eINSTANCE.createChangeContext(); - setRefWidget.setExpression(AQLUtils.getSelfServiceCallExpression("handleReferenceWidgetNewValue", List.of(E_STRUCTURAL_FEATURE + ".name", ViewFormDescriptionConverter.NEW_VALUE))); + setRefWidget.setExpression(ServiceMethod.of2(DetailsViewService::handleReferenceWidgetNewValue).aqlSelf(E_STRUCTURAL_FEATURE + ".name", ViewFormDescriptionConverter.NEW_VALUE)); refWidget.getBody().add(setRefWidget); return refWidget; } diff --git a/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/DiagramMutationCompartmentService.java b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/DiagramMutationCompartmentService.java new file mode 100644 index 000000000..b91d7bd54 --- /dev/null +++ b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/DiagramMutationCompartmentService.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * 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.diagram.services; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Stream; + +import org.eclipse.sirius.components.collaborative.diagrams.DiagramContext; +import org.eclipse.sirius.components.collaborative.diagrams.DiagramService; +import org.eclipse.sirius.components.collaborative.diagrams.DiagramServices; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectSearchService; +import org.eclipse.sirius.components.diagrams.FreeFormLayoutStrategy; +import org.eclipse.sirius.components.diagrams.ListLayoutStrategy; +import org.eclipse.sirius.components.diagrams.Node; +import org.eclipse.sirius.components.diagrams.ViewModifier; +import org.eclipse.sirius.components.diagrams.description.NodeDescription; +import org.eclipse.syson.diagram.services.utils.RevealCompartmentSwitch; +import org.eclipse.syson.services.NodeDescriptionService; +import org.eclipse.syson.services.UtilService; +import org.eclipse.syson.sysml.Element; +import org.eclipse.syson.util.NodeFinder; +import org.eclipse.syson.util.StandardDiagramsConstants; +import org.springframework.stereotype.Service; + +/** + * Mutation services related to diagram compartments. + * + * @author arichard + */ +@Service +public class DiagramMutationCompartmentService { + + private final IObjectSearchService objectSearchService; + + private final UtilService utilService; + + private final DiagramQueryViewService diagramQueryViewService; + + public DiagramMutationCompartmentService(IObjectSearchService objectSearchService, DiagramQueryViewService diagramQueryViewService) { + this.objectSearchService = Objects.requireNonNull(objectSearchService); + this.utilService = new UtilService(); + this.diagramQueryViewService = Objects.requireNonNull(diagramQueryViewService); + } + + /** + * Reveals the compartment in {@code node} that can display {@code targetElement}. + */ + public Node revealCompartment(Node node, Element targetElement, DiagramContext diagramContext, IEditingContext editingContext, + Map convertedNodes) { + + if (!this.utilService.isUnsynchronized(targetElement) + && !this.needToRevealCompartment(targetElement, this.diagramQueryViewService.isView(targetElement, StandardDiagramsConstants.GV_QN, node, editingContext, diagramContext))) { + return node; + } + var nodeDescription = convertedNodes.values().stream() + .filter(nodeDesc -> Objects.equals(nodeDesc.getId(), node.getDescriptionId())) + .findFirst(); + + List allChildNodeDescriptions = nodeDescription.map(nodeDesc -> Stream.concat( + nodeDesc.getChildNodeDescriptions().stream(), + convertedNodes.values().stream().filter(convNode -> nodeDesc.getReusedChildNodeDescriptionIds().contains(convNode.getId()))) + .toList()) + .orElse(List.of()); + + var parentObject = this.objectSearchService.getObject(editingContext, node.getTargetObjectId()).orElse(null); + NodeDescriptionService nodeDescriptionService = new NodeDescriptionService(this.objectSearchService); + + var compartmentDescriptionCandidates = nodeDescriptionService.getNodeDescriptionsForRenderingElementAsChild(targetElement, parentObject, allChildNodeDescriptions, + convertedNodes, editingContext, diagramContext).stream() + .map(NodeDescription::getId) + .toList(); + + if (!compartmentDescriptionCandidates.isEmpty()) { + NodeFinder nodeFinder = new NodeFinder(diagramContext.diagram()); + List compartmentNodeCandidates = nodeFinder + .getAllNodesMatching(n -> compartmentDescriptionCandidates.stream().anyMatch(id -> Objects.equals(id, n.getDescriptionId())) + && Objects.equals(n.getTargetObjectId(), node.getTargetObjectId())); + var noCompartmentToHandleTargetElement = compartmentNodeCandidates.stream() + .allMatch(candidate -> ViewModifier.Hidden.equals(candidate.getState())); + if (noCompartmentToHandleTargetElement) { + compartmentNodeCandidates.stream().reduce((previousCandidate, newCandidate) -> { + if (previousCandidate.getStyle().getChildrenLayoutStrategy() instanceof ListLayoutStrategy && newCandidate.getStyle().getChildrenLayoutStrategy() instanceof FreeFormLayoutStrategy) { + return newCandidate; + } + return previousCandidate; + }).ifPresent(compartmentToReveal -> new DiagramServices().reveal(new DiagramService(diagramContext), List.of(compartmentToReveal))); + } + } + return node; + } + + private boolean needToRevealCompartment(Element element, boolean isGeneralView) { + return new RevealCompartmentSwitch(isGeneralView).doSwitch(element); + } +} diff --git a/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/DiagramQueryAnnotatingService.java b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/DiagramQueryAnnotatingService.java new file mode 100644 index 000000000..b21a1fa73 --- /dev/null +++ b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/DiagramQueryAnnotatingService.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * 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.diagram.services; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Stream; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.sirius.components.collaborative.diagrams.DiagramContext; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectSearchService; +import org.eclipse.sirius.components.diagrams.Edge; +import org.eclipse.sirius.components.diagrams.IDiagramElement; +import org.eclipse.sirius.components.diagrams.Node; +import org.eclipse.syson.sysml.AnnotatingElement; +import org.eclipse.syson.sysml.Element; +import org.eclipse.syson.sysml.ViewUsage; +import org.springframework.stereotype.Service; + +/** + * Query services related to annotating nodes. + * + * @author arichard + */ +@Service +public class DiagramQueryAnnotatingService { + + private final IObjectSearchService objectSearchService; + + public DiagramQueryAnnotatingService(IObjectSearchService objectSearchService) { + this.objectSearchService = Objects.requireNonNull(objectSearchService); + } + + /** + * Returns {@code true} if the provided annotated element of the given {@code element} is represented on the + * diagram, {@code false} otherwise. + */ + public boolean showAnnotatingNode(Element element, DiagramContext diagramContext, IEditingContext editingContext) { + boolean displayAnnotatingNode = false; + if (element instanceof AnnotatingElement ae && diagramContext != null && editingContext != null) { + EList annotatedElements = ae.getAnnotatedElement(); + IDiagramElement matchingDiagramElement = null; + + displayAnnotatingNode = this.isAnnotatingNodeOnRoot(diagramContext, editingContext, annotatedElements); + + if (!displayAnnotatingNode) { + for (Node node : diagramContext.diagram().getNodes()) { + matchingDiagramElement = this.getOneMatchingAnnotatedNode(node, annotatedElements, diagramContext, editingContext); + if (matchingDiagramElement != null) { + displayAnnotatingNode = true; + break; + } + } + } + if (!displayAnnotatingNode) { + for (Edge edge : diagramContext.diagram().getEdges()) { + matchingDiagramElement = this.getOneMatchingAnnotatedEdge(edge, annotatedElements, diagramContext, editingContext); + if (matchingDiagramElement != null) { + displayAnnotatingNode = true; + break; + } + } + } + } else { + displayAnnotatingNode = true; + } + return displayAnnotatingNode; + } + + private boolean isAnnotatingNodeOnRoot(DiagramContext diagramContext, IEditingContext editingContext, EList annotatedElements) { + boolean isAnnotatingNodeOnRoot = false; + String diagramTargetObjectId = diagramContext.diagram().getTargetObjectId(); + Element diagramTargetObject = this.objectSearchService.getObject(editingContext, diagramTargetObjectId).stream() + .filter(Element.class::isInstance) + .map(Element.class::cast) + .findFirst() + .orElse(null); + if (diagramTargetObject instanceof ViewUsage viewUsage) { + if (annotatedElements.contains(viewUsage)) { + isAnnotatingNodeOnRoot = true; + } else { + isAnnotatingNodeOnRoot = annotatedElements.contains(viewUsage.getOwner()); + } + } + return isAnnotatingNodeOnRoot; + } + + private Edge getOneMatchingAnnotatedEdge(Edge edge, List annotatedElements, DiagramContext diagramContext, IEditingContext editingContext) { + Edge matchingAnnotatedEdge = null; + Optional semanticNodeOpt = this.objectSearchService.getObject(editingContext, edge.getTargetObjectId()); + if (semanticNodeOpt.isPresent()) { + if (annotatedElements.contains(semanticNodeOpt.get())) { + boolean isDeletingAnnotatingEdge = diagramContext.viewDeletionRequests().stream() + .anyMatch(viewDeletionRequest -> Objects.equals(viewDeletionRequest.getElementId(), edge.getId())); + if (!isDeletingAnnotatingEdge) { + matchingAnnotatedEdge = edge; + } + return matchingAnnotatedEdge; + } + } + return matchingAnnotatedEdge; + } + + private Node getOneMatchingAnnotatedNode(Node node, List annotatedElements, DiagramContext diagramContext, IEditingContext editingContext) { + Node matchingAnnotatedNode = null; + Optional semanticNodeOpt = this.objectSearchService.getObject(editingContext, node.getTargetObjectId()); + if (semanticNodeOpt.isPresent()) { + if (annotatedElements.contains(semanticNodeOpt.get())) { + boolean isDeletingAnnotatingNode = diagramContext.viewDeletionRequests().stream() + .anyMatch(viewDeletionRequest -> Objects.equals(viewDeletionRequest.getElementId(), node.getId())); + if (!isDeletingAnnotatingNode) { + matchingAnnotatedNode = node; + } + return matchingAnnotatedNode; + } + } + matchingAnnotatedNode = this.getFirstMatchingChildAnnotatedNode(node, annotatedElements, diagramContext, editingContext); + return matchingAnnotatedNode; + } + + private Node getFirstMatchingChildAnnotatedNode(Node node, List annotatedElements, DiagramContext diagramContext, IEditingContext editingContext) { + List childrenNodes = Stream.concat(node.getChildNodes().stream(), node.getBorderNodes().stream()).toList(); + for (Node childNode : childrenNodes) { + Node matchingChildAnnotatedNode = this.getOneMatchingAnnotatedNode(childNode, annotatedElements, diagramContext, editingContext); + if (matchingChildAnnotatedNode != null) { + return matchingChildAnnotatedNode; + } + } + return null; + } +} diff --git a/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/DiagramQueryExposeService.java b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/DiagramQueryExposeService.java new file mode 100644 index 000000000..35b76a90c --- /dev/null +++ b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/DiagramQueryExposeService.java @@ -0,0 +1,194 @@ +/******************************************************************************* + * 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.diagram.services; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Stream; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.sirius.components.collaborative.diagrams.DiagramContext; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.syson.diagram.services.utils.ViewFilterSwitch; +import org.eclipse.syson.services.UtilService; +import org.eclipse.syson.sysml.Element; +import org.eclipse.syson.sysml.Expose; +import org.eclipse.syson.sysml.LibraryPackage; +import org.eclipse.syson.sysml.MembershipExpose; +import org.eclipse.syson.sysml.Package; +import org.eclipse.syson.sysml.PartUsage; +import org.eclipse.syson.sysml.ReferenceUsage; +import org.eclipse.syson.sysml.SysmlPackage; +import org.eclipse.syson.sysml.ViewUsage; +import org.eclipse.syson.sysml.helper.EMFUtils; +import org.eclipse.syson.sysml.metamodel.services.MetamodelQueryElementService; +import org.springframework.stereotype.Service; + +/** + * Query services related to exposed elements in diagrams. + * + * @author arichard + */ +@Service +public class DiagramQueryExposeService { + + private final MetamodelQueryElementService metamodelQueryElementService; + + private final UtilService utilService; + + public DiagramQueryExposeService() { + this.metamodelQueryElementService = new MetamodelQueryElementService(); + this.utilService = new UtilService(); + } + + /** + * Get the list of elements to expose for a given {@link Element}. + */ + public List getExposedElements(Element element, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext) { + return this.getExposedElements(element, null, domainType, ancestors, editingContext, diagramContext); + } + + /** + * Get the list of elements to expose for a given {@link Element}. + */ + public List getExposedElements(Element element, Element parent, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext) { + List elementsToExpose = new ArrayList<>(); + if (element instanceof ViewUsage viewUsage) { + var exposedElements = new ArrayList(); + if (parent == null) { + exposedElements.addAll(this.getDirectExposedElements(viewUsage)); + } else { + exposedElements.addAll(viewUsage.getExposedElement()); + } + var filteredExposedElements = exposedElements.stream() + .filter(elt -> this.isTypeOf(elt, domainType) && (parent == null || (!Objects.equals(parent, elt) && EMFUtils.isAncestor(parent, elt)))) + .toList(); + elementsToExpose.addAll(filteredExposedElements); + var viewDefKind = this.utilService.getViewDefinitionKind(viewUsage, ancestors, editingContext); + for (Element filteredExposedElement : filteredExposedElements) { + boolean canBeDisplayed = new ViewFilterSwitch(viewDefKind, exposedElements, parent, this.metamodelQueryElementService).doSwitch(filteredExposedElement); + if (!canBeDisplayed) { + elementsToExpose.remove(filteredExposedElement); + } + } + } else if (ancestors != null) { + var viewUsageContainingElement = ancestors.stream() + .filter(ViewUsage.class::isInstance) + .map(ViewUsage.class::cast) + .findFirst(); + if (viewUsageContainingElement.isPresent()) { + elementsToExpose.addAll(this.getExposedElements(viewUsageContainingElement.get(), element, domainType, ancestors, editingContext, diagramContext)); + } + } + return elementsToExpose; + } + + /** + * Get all Actors ({@link PartUsage}) in {@link ViewUsage}'s exposed elements. + */ + public List getExposedActors(Element element, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext) { + return this.getExposedElements(element, domainType, ancestors, editingContext, diagramContext).stream() + .filter(PartUsage.class::isInstance) + .map(PartUsage.class::cast) + .filter(this.metamodelQueryElementService::isActor) + .toList(); + } + + /** + * Get all Stakeholders ({@link PartUsage}) in {@link ViewUsage}'s exposed elements. + */ + public List getExposedStakeholders(Element element, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext) { + return this.getExposedElements(element, domainType, ancestors, editingContext, diagramContext).stream() + .filter(PartUsage.class::isInstance) + .map(PartUsage.class::cast) + .filter(this.metamodelQueryElementService::isStakeholder) + .toList(); + } + + /** + * Get all Subjects ({@link ReferenceUsage}) in {@link ViewUsage}'s exposed elements. + */ + public List getExposedSubjects(Element element, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext) { + return this.getExposedElements(element, domainType, ancestors, editingContext, diagramContext).stream() + .filter(ReferenceUsage.class::isInstance) + .map(ReferenceUsage.class::cast) + .filter(this.metamodelQueryElementService::isSubject) + .toList(); + } + + public List getAllReachableRequirements(EObject eObject) { + List allRequirementUsages = this.utilService.getAllReachableType(eObject, SysmlPackage.eINSTANCE.getRequirementUsage(), false); + List allRequirementDefinitions = this.utilService.getAllReachableType(eObject, SysmlPackage.eINSTANCE.getRequirementDefinition(), false); + return Stream.concat(allRequirementUsages.stream(), allRequirementDefinitions.stream()) + .filter(Element.class::isInstance) + .map(Element.class::cast) + .toList(); + } + + Set getDirectExposedElements(ViewUsage viewUsage) { + var directExposedElements = new HashSet(); + List exposedElements = viewUsage.getOwnedRelationship().stream() + .filter(Expose.class::isInstance) + .map(Expose.class::cast) + .toList(); + for (Expose exposedElement : exposedElements) { + Element importedElement = exposedElement.getImportedElement(); + if (importedElement instanceof Package) { + directExposedElements.add(importedElement); + } else if (exposedElement instanceof MembershipExpose membershipExpose) { + var importedMembership = membershipExpose.getImportedMembership(); + if (importedMembership != null) { + var memberElement = importedMembership.getMemberElement(); + if (memberElement != null && !this.isChildOfExposedPackage(memberElement, exposedElements)) { + directExposedElements.add(memberElement); + if (exposedElement.isIsRecursive()) { + directExposedElements.addAll(this.getRecursiveContents(memberElement)); + } + } + } + } + } + return directExposedElements; + } + + private boolean isChildOfExposedPackage(Element element, List exposedElements) { + boolean isChildOfExposedElement = false; + for (Expose exposedElement : exposedElements) { + Element importedElement = exposedElement.getImportedElement(); + if (importedElement instanceof Package && !Objects.equals(element, importedElement) && EMFUtils.isAncestor(importedElement, element)) { + isChildOfExposedElement = true; + break; + } + } + return isChildOfExposedElement; + } + + private List getRecursiveContents(Element element) { + var contents = new ArrayList(); + var ownedElements = element.getOwnedElement().stream().filter(Objects::nonNull).toList(); + contents.addAll(ownedElements); + ownedElements.forEach(oe -> contents.addAll(this.getRecursiveContents(oe))); + return contents; + } + + private boolean isTypeOf(Element element, EClass domainType) { + if (element instanceof LibraryPackage) { + return Objects.equals(SysmlPackage.eINSTANCE.getPackage(), domainType); + } + return element != null && Objects.equals(element.eClass(), domainType); + } +} diff --git a/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/DiagramQueryGraphicalService.java b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/DiagramQueryGraphicalService.java new file mode 100644 index 000000000..33e4efd72 --- /dev/null +++ b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/DiagramQueryGraphicalService.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * 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.diagram.services; + +import java.util.List; + +import org.eclipse.sirius.components.diagrams.elements.NodeElementProps; +import org.eclipse.sirius.components.diagrams.renderer.DiagramRenderingCache; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +/** + * Query services related to graphical containment in rendered diagrams. + * + * @author arichard + */ +@Service +public class DiagramQueryGraphicalService { + + private final Logger logger = LoggerFactory.getLogger(DiagramQueryGraphicalService.class); + + /** + * Returns {@code true} if {@code parentNodeElement} is not an ancestor of {@code childNodeElement}. + * + * @param parentNodeElement + * the element representing the parent node + * @param childNodeElement + * the element representing the child node + * @param cache + * the rendering cache used in the current rendering process + * @return {@code true} if {@code parentNodeElement} is not an ancestor of {@code childNodeElement} + */ + public boolean isNotAncestorOf(org.eclipse.sirius.components.representations.Element parentNodeElement, + org.eclipse.sirius.components.representations.Element childNodeElement, DiagramRenderingCache cache) { + return !this.isAncestorOf(parentNodeElement, childNodeElement, cache); + } + + /** + * Returns {@code true} if {@code parentNodeElement} is an ancestor of {@code childNodeElement}. + * + * @param parentNodeElement + * the element representing the parent node + * @param childNodeElement + * the element representing the child node + * @param cache + * the rendering cache used in the current rendering process + * @return {@code true} if {@code parentNodeElement} is an ancestor of {@code childNodeElement} + */ + private boolean isAncestorOf(org.eclipse.sirius.components.representations.Element parentNodeElement, + org.eclipse.sirius.components.representations.Element childNodeElement, DiagramRenderingCache cache) { + boolean result = false; + if (parentNodeElement.getProps() instanceof NodeElementProps parentNodeProps + && childNodeElement.getProps() instanceof NodeElementProps childNodeProps) { + List ancestorIds = cache.getAncestors(childNodeProps.getId()).stream() + .map(org.eclipse.sirius.components.representations.Element::getProps) + .filter(NodeElementProps.class::isInstance) + .map(NodeElementProps.class::cast) + .map(NodeElementProps::getId) + .toList(); + result = ancestorIds.contains(parentNodeProps.getId()); + } else { + this.logger.warn("Cannot check graphical containment between {} and {}", parentNodeElement, childNodeElement); + } + return result; + } +} diff --git a/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/DiagramQueryViewService.java b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/DiagramQueryViewService.java new file mode 100644 index 000000000..490ff345b --- /dev/null +++ b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/DiagramQueryViewService.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * 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.diagram.services; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import org.eclipse.sirius.components.collaborative.diagrams.DiagramContext; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectSearchService; +import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.diagrams.Node; +import org.eclipse.syson.sysml.Element; +import org.eclipse.syson.sysml.SysmlPackage; +import org.eclipse.syson.sysml.Type; +import org.eclipse.syson.sysml.ViewDefinition; +import org.eclipse.syson.sysml.ViewUsage; +import org.eclipse.syson.sysml.util.ElementUtil; +import org.eclipse.syson.util.NodeFinder; +import org.eclipse.syson.util.StandardDiagramsConstants; +import org.springframework.stereotype.Service; + +/** + * Query services related to diagram view kinds. + * + * @author arichard + */ +@Service +public class DiagramQueryViewService { + + private final IObjectSearchService objectSearchService; + + private final ElementUtil elementUtil; + + private final DiagramQueryExposeService diagramQueryExposeService; + + public DiagramQueryViewService(IObjectSearchService objectSearchService, DiagramQueryExposeService diagramQueryExposeService) { + this.objectSearchService = Objects.requireNonNull(objectSearchService); + this.elementUtil = new ElementUtil(); + this.diagramQueryExposeService = Objects.requireNonNull(diagramQueryExposeService); + } + + /** + * Check if the given {@link Element} displayed in the given {@link DiagramContext} is of the given + * {@link ViewDefinition}. + */ + public boolean isView(Element element, String viewDefinition, List ancestors, IEditingContext editingContext, DiagramContext diagramContext) { + boolean isView = false; + if (element instanceof ViewUsage viewUsage) { + var types = viewUsage.getType(); + if ((types == null || types.isEmpty()) && Objects.equals(StandardDiagramsConstants.GV_QN, viewDefinition)) { + isView = true; + } else { + var expectedViewDefinition = this.elementUtil.findByNameAndType(viewUsage, viewDefinition, ViewDefinition.class); + Type type = types.get(0); + isView = Objects.equals(type, expectedViewDefinition); + } + } else { + var viewUsageContainingElement = ancestors.stream().filter(ViewUsage.class::isInstance).map(ViewUsage.class::cast).findFirst(); + if (viewUsageContainingElement.isPresent()) { + isView = this.isView(viewUsageContainingElement.get(), viewDefinition, ancestors, editingContext, diagramContext); + } + } + return isView; + } + + /** + * Check if the given {@link Element} displayed in the given {@link DiagramContext} is of the given + * {@link ViewDefinition}. + */ + public boolean isView(Element element, String viewDefinition, Node selectedNode, IEditingContext editingContext, DiagramContext diagramContext) { + boolean isView = false; + if (element instanceof ViewUsage viewUsage) { + var types = viewUsage.getType(); + if ((types == null || types.isEmpty()) && Objects.equals(StandardDiagramsConstants.GV_QN, viewDefinition)) { + isView = true; + } else { + var expectedViewDefinition = this.elementUtil.findByNameAndType(viewUsage, viewDefinition, ViewDefinition.class); + Type type = types.get(0); + isView = Objects.equals(type, expectedViewDefinition); + } + } else { + var ancestors = this.getAncestors(selectedNode, diagramContext.diagram(), editingContext); + var viewUsageContainingElement = ancestors.stream().filter(ViewUsage.class::isInstance).map(ViewUsage.class::cast).findFirst(); + if (viewUsageContainingElement.isPresent()) { + isView = this.isView(viewUsageContainingElement.get(), viewDefinition, selectedNode, editingContext, diagramContext); + } + } + return isView; + } + + /** + * Check if the compartment associated to the given {@link Element} should be hidden by default. + */ + public boolean isHiddenByDefault(Element self, String compartmentName, List ancestors, IEditingContext editingContext, DiagramContext diagramContext) { + boolean isHiddenByDefault = true; + if ("GV Compartment interconnection FreeForm".equals(compartmentName)) { + var exposedParts = this.diagramQueryExposeService.getExposedElements(self, SysmlPackage.eINSTANCE.getPartUsage(), ancestors, editingContext, diagramContext); + var exposedActions = this.diagramQueryExposeService.getExposedElements(self, SysmlPackage.eINSTANCE.getActionUsage(), ancestors, editingContext, diagramContext); + var exposedSatisfyRequirements = this.diagramQueryExposeService.getExposedElements(self, SysmlPackage.eINSTANCE.getSatisfyRequirementUsage(), ancestors, editingContext, diagramContext); + if (!exposedParts.isEmpty() || !exposedActions.isEmpty() || !exposedSatisfyRequirements.isEmpty()) { + isHiddenByDefault = false; + } + } + return isHiddenByDefault; + } + + private List getAncestors(Node selectedNode, Diagram diagram, IEditingContext editingContext) { + var ancestors = new ArrayList<>(); + var parent = new NodeFinder(diagram).getParent(selectedNode); + if (parent instanceof Node parentNode) { + var parentObject = this.objectSearchService.getObject(editingContext, parentNode.getTargetObjectId()); + if (parentObject.isPresent()) { + ancestors.add(parentObject.get()); + ancestors.addAll(this.getAncestors(parentNode, diagram, editingContext)); + } + } else if (parent instanceof Diagram) { + var parentObject = this.objectSearchService.getObject(editingContext, diagram.getTargetObjectId()); + if (parentObject.isPresent()) { + ancestors.add(parentObject.get()); + } + } + return ancestors; + } +} diff --git a/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/aql/DiagramMutationAQLService.java b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/aql/DiagramMutationAQLService.java index 210c71d20..3cc7035ce 100644 --- a/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/aql/DiagramMutationAQLService.java +++ b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/aql/DiagramMutationAQLService.java @@ -20,6 +20,7 @@ import org.eclipse.sirius.components.diagrams.Diagram; import org.eclipse.sirius.components.diagrams.Node; import org.eclipse.sirius.components.diagrams.description.NodeDescription; +import org.eclipse.syson.diagram.services.DiagramMutationCompartmentService; import org.eclipse.syson.diagram.services.DiagramMutationDiagramService; import org.eclipse.syson.diagram.services.DiagramMutationDndService; import org.eclipse.syson.diagram.services.DiagramMutationElementService; @@ -57,13 +58,17 @@ public class DiagramMutationAQLService { private final DiagramMutationDiagramService diagramMutationDiagramService; + private final DiagramMutationCompartmentService diagramMutationCompartmentService; + public DiagramMutationAQLService(DiagramMutationDndService diagramMutationDndService, DiagramMutationElementService diagramMutationElementService, - DiagramMutationExposeService diagramMutationExposeService, DiagramMutationLabelService diagramMutationLabelService, DiagramMutationDiagramService diagramMutationDiagramService) { + DiagramMutationExposeService diagramMutationExposeService, DiagramMutationLabelService diagramMutationLabelService, DiagramMutationDiagramService diagramMutationDiagramService, + DiagramMutationCompartmentService diagramMutationCompartmentService) { this.diagramMutationDndService = Objects.requireNonNull(diagramMutationDndService); this.diagramMutationElementService = Objects.requireNonNull(diagramMutationElementService); this.diagramMutationExposeService = Objects.requireNonNull(diagramMutationExposeService); this.diagramMutationLabelService = Objects.requireNonNull(diagramMutationLabelService); this.diagramMutationDiagramService = Objects.requireNonNull(diagramMutationDiagramService); + this.diagramMutationCompartmentService = Objects.requireNonNull(diagramMutationCompartmentService); } /** @@ -75,10 +80,27 @@ public Element addToExposedElements(Element element, boolean recursive, IEditing } /** - * {@link DiagramMutationDiagramService#duplicateElementAndExpose(Element, IEditingContext, DiagramContext, Node, Map)}. + * {@link DiagramMutationElementService#createBindingConnectorAsUsage(Feature, Feature, Node, Node, IEditingContext, DiagramContext)}. */ - public Element duplicateElementAndExpose(Element element, IEditingContext editingContext, DiagramContext diagramContext, Node node, Map convertedNodes) { - return this.diagramMutationDiagramService.duplicateElementAndExpose(element, editingContext, diagramContext, node, convertedNodes); + public BindingConnectorAsUsage createBindingConnectorAsUsage(Feature source, Feature target, Node sourceNode, Node targetNode, IEditingContext editingContext, + DiagramContext diagramContext) { + return this.diagramMutationElementService.createBindingConnectorAsUsage(source, target, sourceNode, targetNode, editingContext, diagramContext); + } + + /** + * {@link DiagramMutationElementService#createChildState(Element, IEditingContext, DiagramContext, Node, Map, boolean, boolean)}. + */ + public StateUsage createChildState(Element parentState, IEditingContext editingContext, DiagramContext diagramContext, Node selectedNode, + Map convertedNodes, boolean isParallel, boolean isExhibit) { + return this.diagramMutationElementService.createChildState(parentState, editingContext, diagramContext, selectedNode, convertedNodes, isParallel, isExhibit); + } + + /** + * {@link DiagramMutationElementService#createConnectionUsage(Usage, Usage, Node, Node, IEditingContext, DiagramContext)}. + */ + public ConnectionUsage createConnectionUsage(Usage connectionSource, Usage connectionTarget, Node sourceNode, Node targetNode, IEditingContext editingContext, + DiagramContext diagramContext) { + return this.diagramMutationElementService.createConnectionUsage(connectionSource, connectionTarget, sourceNode, targetNode, editingContext, diagramContext); } /** @@ -89,25 +111,33 @@ public Element createDiagram(Element element, IEditingContext editingContext) { } /** - * {@link DiagramMutationElementService#createChildState(Element, IEditingContext, DiagramContext, Node, Map, boolean, boolean)}. + * {@link DiagramMutationElementService#createFlowUsage(Feature, Feature, Node, Node, IEditingContext, DiagramContext)}. */ - public StateUsage createChildState(Element parentState, IEditingContext editingContext, DiagramContext diagramContext, Node selectedNode, - Map convertedNodes, boolean isParallel, boolean isExhibit) { - return this.diagramMutationElementService.createChildState(parentState, editingContext, diagramContext, selectedNode, convertedNodes, isParallel, isExhibit); + public FlowUsage createFlowUsage(Feature source, Feature target, Node sourceNode, Node targetNode, IEditingContext editingContext, + DiagramContext diagramContext) { + return this.diagramMutationElementService.createFlowUsage(source, target, sourceNode, targetNode, editingContext, diagramContext); } /** - * {@link DiagramMutationLabelService#directEdit(Element, String)}. + * {@link DiagramMutationElementService#createFlowUsageWithPayload(ConnectionUsage, Type)}. */ - public Element directEdit(Element element, String newLabel) { - return this.diagramMutationLabelService.directEdit(element, newLabel); + public FlowUsage createFlowUsageWithPayload(ConnectionUsage parent, Type payloadType) { + return this.diagramMutationElementService.createFlowUsageWithPayload(parent, payloadType); } /** - * {@link DiagramMutationLabelService#directEditNode(Element, String)}. + * {@link DiagramMutationElementService#createInterfaceUsage(PortUsage, PortUsage, Node, Node, IEditingContext, DiagramContext)}. */ - public Element directEditNode(Element element, String newLabel) { - return this.diagramMutationLabelService.directEditNode(element, newLabel); + public InterfaceUsage createInterfaceUsage(PortUsage sourcePort, PortUsage targetPort, Node sourceNode, Node targetNode, IEditingContext editingContext, + DiagramContext diagramContext) { + return this.diagramMutationElementService.createInterfaceUsage(sourcePort, targetPort, sourceNode, targetNode, editingContext, diagramContext); + } + + /** + * {@link DiagramMutationLabelService#directEdit(Element, String)}. + */ + public Element directEdit(Element element, String newLabel) { + return this.diagramMutationLabelService.directEdit(element, newLabel); } /** @@ -117,6 +147,13 @@ public Element directEditListItem(Element element, String newLabel) { return this.diagramMutationLabelService.directEditListItem(element, newLabel); } + /** + * {@link DiagramMutationLabelService#directEditNode(Element, String)}. + */ + public Element directEditNode(Element element, String newLabel) { + return this.diagramMutationLabelService.directEditNode(element, newLabel); + } + /** * {@link DiagramMutationDndService#dropElementFromDiagram(Element, Node, Element, Node, IEditingContext, DiagramContext, Map)}. */ @@ -126,29 +163,29 @@ public Element dropElementFromDiagram(Element droppedElement, Node droppedNode, } /** - * {@link DiagramMutationDndService#dropElementFromDiagramInRequirementAssumeConstraintCompartment(Element, Node, Element, Node, IEditingContext, DiagramContext, Map)}. + * {@link DiagramMutationDndService#dropElementFromDiagramInConstraintCompartment(Element, Node, Element, Node, IEditingContext, DiagramContext, Map)}. */ - public Element dropElementFromDiagramInRequirementAssumeConstraintCompartment(Element droppedElement, Node droppedNode, Element targetElement, Node targetNode, IEditingContext editingContext, + public Element dropElementFromDiagramInConstraintCompartment(Element droppedElement, Node droppedNode, Element targetElement, Node targetNode, IEditingContext editingContext, DiagramContext diagramContext, Map convertedNodes) { - return this.diagramMutationDndService.dropElementFromDiagramInRequirementAssumeConstraintCompartment(droppedElement, droppedNode, targetElement, targetNode, editingContext, diagramContext, + return this.diagramMutationDndService.dropElementFromDiagramInConstraintCompartment(droppedElement, droppedNode, targetElement, targetNode, editingContext, diagramContext, convertedNodes); } /** - * {@link DiagramMutationDndService#dropElementFromDiagramInRequirementRequireConstraintCompartment(Element, Node, Element, Node, IEditingContext, DiagramContext, Map)}. + * {@link DiagramMutationDndService#dropElementFromDiagramInRequirementAssumeConstraintCompartment(Element, Node, Element, Node, IEditingContext, DiagramContext, Map)}. */ - public Element dropElementFromDiagramInRequirementRequireConstraintCompartment(Element droppedElement, Node droppedNode, Element targetElement, Node targetNode, IEditingContext editingContext, + public Element dropElementFromDiagramInRequirementAssumeConstraintCompartment(Element droppedElement, Node droppedNode, Element targetElement, Node targetNode, IEditingContext editingContext, DiagramContext diagramContext, Map convertedNodes) { - return this.diagramMutationDndService.dropElementFromDiagramInRequirementRequireConstraintCompartment(droppedElement, droppedNode, targetElement, targetNode, editingContext, diagramContext, + return this.diagramMutationDndService.dropElementFromDiagramInRequirementAssumeConstraintCompartment(droppedElement, droppedNode, targetElement, targetNode, editingContext, diagramContext, convertedNodes); } /** - * {@link DiagramMutationDndService#dropElementFromDiagramInConstraintCompartment(Element, Node, Element, Node, IEditingContext, DiagramContext, Map)}. + * {@link DiagramMutationDndService#dropElementFromDiagramInRequirementRequireConstraintCompartment(Element, Node, Element, Node, IEditingContext, DiagramContext, Map)}. */ - public Element dropElementFromDiagramInConstraintCompartment(Element droppedElement, Node droppedNode, Element targetElement, Node targetNode, IEditingContext editingContext, + public Element dropElementFromDiagramInRequirementRequireConstraintCompartment(Element droppedElement, Node droppedNode, Element targetElement, Node targetNode, IEditingContext editingContext, DiagramContext diagramContext, Map convertedNodes) { - return this.diagramMutationDndService.dropElementFromDiagramInConstraintCompartment(droppedElement, droppedNode, targetElement, targetNode, editingContext, diagramContext, + return this.diagramMutationDndService.dropElementFromDiagramInRequirementRequireConstraintCompartment(droppedElement, droppedNode, targetElement, targetNode, editingContext, diagramContext, convertedNodes); } @@ -177,10 +214,11 @@ public Element dropSubjectFromDiagram(Element droppedElement, Node droppedNode, } /** - * {@link DiagramMutationLabelService#editMultiplicityRangeCenterLabel(Element, String)}. + * {@link DiagramMutationDiagramService#duplicateElementAndExpose(Element, IEditingContext, DiagramContext, Node, Map)}. */ - public Element editMultiplicityRangeCenterLabel(Element element, String newLabel) { - return this.diagramMutationLabelService.editMultiplicityRangeCenterLabel(element, newLabel); + public Element duplicateElementAndExpose(Element element, IEditingContext editingContext, DiagramContext diagramContext, Node node, + Map convertedNodes) { + return this.diagramMutationDiagramService.duplicateElementAndExpose(element, editingContext, diagramContext, node, convertedNodes); } /** @@ -191,39 +229,32 @@ public Element editEdgeCenterLabel(Element element, String newLabel) { } /** - * {@link DiagramMutationExposeService#expose(Element, IEditingContext, DiagramContext, Node, Map)}. - */ - public Element expose(Element element, IEditingContext editingContext, DiagramContext diagramContext, Node selectedNode, - Map convertedNodes) { - return this.diagramMutationExposeService.expose(element, editingContext, diagramContext, selectedNode, convertedNodes); - } - - /** - * {@link DiagramMutationExposeService#removeFromExposedElements(Element, Node, IEditingContext, DiagramContext)}. + * {@link DiagramMutationLabelService#editMultiplicityRangeCenterLabel(Element, String)}. */ - public boolean removeFromExposedElements(Element element, Node selectedNode, IEditingContext editingContext, DiagramContext diagramContext) { - return this.diagramMutationExposeService.removeFromExposedElements(element, selectedNode, editingContext, diagramContext); + public Element editMultiplicityRangeCenterLabel(Element element, String newLabel) { + return this.diagramMutationLabelService.editMultiplicityRangeCenterLabel(element, newLabel); } /** - * {@link DiagramMutationElementService#showContentAsNested(Element, Node, IEditingContext, DiagramContext)}. + * {@link DiagramMutationExposeService#expose(Element, IEditingContext, DiagramContext, Node, Map)}. */ - public Element showContentAsNested(Element element, Node selectedNode, IEditingContext editingContext, DiagramContext diagramContext) { - return this.diagramMutationElementService.showContentAsNested(element, selectedNode, editingContext, diagramContext); + public Element expose(Element element, IEditingContext editingContext, DiagramContext diagramContext, Node selectedNode, + Map convertedNodes) { + return this.diagramMutationExposeService.expose(element, editingContext, diagramContext, selectedNode, convertedNodes); } /** - * {@link DiagramMutationElementService#showContentAsTree(Element, Node, IEditingContext, DiagramContext)}. + * {@link DiagramMutationElementService#reconnectSatisfyRequirementSource(SatisfyRequirementUsage, Element)}. */ - public Element showContentAsTree(Element element, Node selectedNode, IEditingContext editingContext, DiagramContext diagramContext) { - return this.diagramMutationElementService.showContentAsTree(element, selectedNode, editingContext, diagramContext); + public SatisfyRequirementUsage reconnectSatisfyRequirementSource(SatisfyRequirementUsage sru, Element newSource) { + return this.diagramMutationElementService.reconnectSatisfyRequirementSource(sru, newSource); } /** - * {@link DiagramMutationElementService#viewNodeAs(Element, String, IEditingContext, DiagramContext, Node)}. + * {@link DiagramMutationElementService#reconnectSatisfyRequirementTarget(SatisfyRequirementUsage, Element)}. */ - public Element viewNodeAs(Element element, String newViewDefinition, IEditingContext editingContext, DiagramContext diagramContext, Node selectedNode) { - return this.diagramMutationElementService.viewNodeAs(element, newViewDefinition, editingContext, diagramContext, selectedNode); + public SatisfyRequirementUsage reconnectSatisfyRequirementTarget(SatisfyRequirementUsage sru, Element newTarget) { + return this.diagramMutationElementService.reconnectSatisfyRequirementTarget(sru, newTarget); } /** @@ -242,58 +273,39 @@ public Connector reconnectTarget(Connector connector, Feature newTarget, Node so return this.diagramMutationElementService.reconnectTarget(connector, newTarget, sourceNode, newTargetNode, editingContext, diagram); } - - /** - * {@link DiagramMutationElementService#reconnectSatisfyRequirementSource(SatisfyRequirementUsage, Element)}. - */ - public SatisfyRequirementUsage reconnectSatisfyRequirementSource(SatisfyRequirementUsage sru, Element newSource) { - return this.diagramMutationElementService.reconnectSatisfyRequirementSource(sru, newSource); - } - /** - * {@link DiagramMutationElementService#reconnectSatisfyRequirementTarget(SatisfyRequirementUsage, Element)}. - */ - public SatisfyRequirementUsage reconnectSatisfyRequirementTarget(SatisfyRequirementUsage sru, Element newTarget) { - return this.diagramMutationElementService.reconnectSatisfyRequirementTarget(sru, newTarget); - } - - /** - * {@link DiagramMutationElementService#createConnectionUsage(Usage, Usage, Node, Node, IEditingContext, DiagramContext)}. + * {@link DiagramMutationExposeService#removeFromExposedElements(Element, Node, IEditingContext, DiagramContext)}. */ - public ConnectionUsage createConnectionUsage(Usage connectionSource, Usage connectionTarget, Node sourceNode, Node targetNode, IEditingContext editingContext, - DiagramContext diagramContext) { - return this.diagramMutationElementService.createConnectionUsage(connectionSource, connectionTarget, sourceNode, targetNode, editingContext, diagramContext); + public boolean removeFromExposedElements(Element element, Node selectedNode, IEditingContext editingContext, DiagramContext diagramContext) { + return this.diagramMutationExposeService.removeFromExposedElements(element, selectedNode, editingContext, diagramContext); } /** - * {@link DiagramMutationElementService#createInterfaceUsage(PortUsage, PortUsage, Node, Node, IEditingContext, DiagramContext)}. + * {@link DiagramMutationCompartmentService#revealCompartment(Node, Element, DiagramContext, IEditingContext, Map)}. */ - public InterfaceUsage createInterfaceUsage(PortUsage sourcePort, PortUsage targetPort, Node sourceNode, Node targetNode, IEditingContext editingContext, - DiagramContext diagramContext) { - return this.diagramMutationElementService.createInterfaceUsage(sourcePort, targetPort, sourceNode, targetNode, editingContext, diagramContext); + public Node revealCompartment(Node node, Element targetElement, DiagramContext diagramContext, IEditingContext editingContext, + Map convertedNodes) { + return this.diagramMutationCompartmentService.revealCompartment(node, targetElement, diagramContext, editingContext, convertedNodes); } /** - * {@link DiagramMutationElementService#createFlowUsage(Feature, Feature, Node, Node, IEditingContext, DiagramContext)}. + * {@link DiagramMutationElementService#showContentAsNested(Element, Node, IEditingContext, DiagramContext)}. */ - public FlowUsage createFlowUsage(Feature source, Feature target, Node sourceNode, Node targetNode, IEditingContext editingContext, - DiagramContext diagramContext) { - return this.diagramMutationElementService.createFlowUsage(source, target, sourceNode, targetNode, editingContext, diagramContext); + public Element showContentAsNested(Element element, Node selectedNode, IEditingContext editingContext, DiagramContext diagramContext) { + return this.diagramMutationElementService.showContentAsNested(element, selectedNode, editingContext, diagramContext); } /** - * {@link DiagramMutationElementService#createBindingConnectorAsUsage(Feature, Feature, Node, Node, IEditingContext, DiagramContext)}. + * {@link DiagramMutationElementService#showContentAsTree(Element, Node, IEditingContext, DiagramContext)}. */ - public BindingConnectorAsUsage createBindingConnectorAsUsage(Feature source, Feature target, Node sourceNode, Node targetNode, IEditingContext editingContext, - DiagramContext diagramContext) { - return this.diagramMutationElementService.createBindingConnectorAsUsage(source, target, sourceNode, targetNode, editingContext, diagramContext); + public Element showContentAsTree(Element element, Node selectedNode, IEditingContext editingContext, DiagramContext diagramContext) { + return this.diagramMutationElementService.showContentAsTree(element, selectedNode, editingContext, diagramContext); } /** - * {@link DiagramMutationElementService#createFlowUsageWithPayload(ConnectionUsage, Type)}. + * {@link DiagramMutationElementService#viewNodeAs(Element, String, IEditingContext, DiagramContext, Node)}. */ - public FlowUsage createFlowUsageWithPayload(ConnectionUsage parent, Type payloadType) { - return this.diagramMutationElementService.createFlowUsageWithPayload(parent, payloadType); + public Element viewNodeAs(Element element, String newViewDefinition, IEditingContext editingContext, DiagramContext diagramContext, Node selectedNode) { + return this.diagramMutationElementService.viewNodeAs(element, newViewDefinition, editingContext, diagramContext, selectedNode); } - } diff --git a/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/aql/DiagramQueryAQLService.java b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/aql/DiagramQueryAQLService.java index f6b54dec2..eecfab937 100644 --- a/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/aql/DiagramQueryAQLService.java +++ b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/aql/DiagramQueryAQLService.java @@ -12,20 +12,30 @@ *******************************************************************************/ package org.eclipse.syson.diagram.services.aql; +import java.util.List; import java.util.Objects; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; import org.eclipse.sirius.components.collaborative.diagrams.DiagramContext; import org.eclipse.sirius.components.core.api.IEditingContext; import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.diagrams.Node; import org.eclipse.sirius.components.diagrams.renderer.DiagramRenderingCache; +import org.eclipse.syson.diagram.services.DiagramQueryAnnotatingService; import org.eclipse.syson.diagram.services.DiagramQueryElementService; +import org.eclipse.syson.diagram.services.DiagramQueryExposeService; +import org.eclipse.syson.diagram.services.DiagramQueryGraphicalService; import org.eclipse.syson.diagram.services.DiagramQueryLabelService; +import org.eclipse.syson.diagram.services.DiagramQueryViewService; import org.eclipse.syson.sysml.Comment; import org.eclipse.syson.sysml.ConnectionUsage; import org.eclipse.syson.sysml.Connector; import org.eclipse.syson.sysml.Dependency; import org.eclipse.syson.sysml.Documentation; import org.eclipse.syson.sysml.Element; +import org.eclipse.syson.sysml.PartUsage; +import org.eclipse.syson.sysml.ReferenceUsage; import org.eclipse.syson.sysml.SatisfyRequirementUsage; import org.eclipse.syson.sysml.TextualRepresentation; import org.eclipse.syson.sysml.TransitionUsage; @@ -43,9 +53,37 @@ public class DiagramQueryAQLService { private final DiagramQueryLabelService diagramQueryLabelService; - public DiagramQueryAQLService(DiagramQueryElementService diagramQueryElementService, DiagramQueryLabelService diagramQueryLabelService) { + private final DiagramQueryExposeService diagramQueryExposeService; + + private final DiagramQueryGraphicalService diagramQueryGraphicalService; + + private final DiagramQueryViewService diagramQueryViewService; + + private final DiagramQueryAnnotatingService diagramQueryAnnotatingService; + + public DiagramQueryAQLService(DiagramQueryElementService diagramQueryElementService, DiagramQueryLabelService diagramQueryLabelService, + DiagramQueryExposeService diagramQueryExposeService, DiagramQueryGraphicalService diagramQueryGraphicalService, DiagramQueryViewService diagramQueryViewService, + DiagramQueryAnnotatingService diagramQueryAnnotatingService) { this.diagramQueryElementService = Objects.requireNonNull(diagramQueryElementService); this.diagramQueryLabelService = Objects.requireNonNull(diagramQueryLabelService); + this.diagramQueryExposeService = Objects.requireNonNull(diagramQueryExposeService); + this.diagramQueryGraphicalService = Objects.requireNonNull(diagramQueryGraphicalService); + this.diagramQueryViewService = Objects.requireNonNull(diagramQueryViewService); + this.diagramQueryAnnotatingService = Objects.requireNonNull(diagramQueryAnnotatingService); + } + + /** + * {@link DiagramQueryElementService#canCreateFlowUsage(ConnectionUsage)}. + */ + public boolean canCreateFlowUsage(ConnectionUsage connection) { + return this.diagramQueryElementService.canCreateFlowUsage(connection); + } + + /** + * {@link DiagramQueryExposeService#getAllReachableRequirements(EObject)}. + */ + public List getAllReachableRequirements(EObject eObject) { + return this.diagramQueryExposeService.getAllReachableRequirements(eObject); } /** @@ -69,6 +107,13 @@ public String getCompartmentItemLabel(Element element) { return compartmentItemLabel; } + /** + * {@link DiagramQueryLabelService#getConnectionUsageLabel(ConnectionUsage)}. + */ + public String getConnectionUsageLabel(ConnectionUsage element) { + return this.diagramQueryLabelService.getConnectionUsageLabel(element); + } + /** * {@link DiagramQueryLabelService#getContainerLabel(Element)}. */ @@ -108,10 +153,38 @@ public String getEdgeLabel(Element element) { } /** - * {@link DiagramQueryLabelService#getConnectionUsageLabel(ConnectionUsage)}. + * {@link DiagramQueryExposeService#getExposedActors(Element, EClass, List, IEditingContext, DiagramContext)}. */ - public String getConnectionUsageLabel(ConnectionUsage element) { - return this.diagramQueryLabelService.getConnectionUsageLabel(element); + public List getExposedActors(Element element, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext) { + return this.diagramQueryExposeService.getExposedActors(element, domainType, ancestors, editingContext, diagramContext); + } + + /** + * {@link DiagramQueryExposeService#getExposedElements(Element, EClass, List, IEditingContext, DiagramContext)}. + */ + public List getExposedElements(Element element, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext) { + return this.diagramQueryExposeService.getExposedElements(element, domainType, ancestors, editingContext, diagramContext); + } + + /** + * {@link DiagramQueryExposeService#getExposedElements(Element, Element, EClass, List, IEditingContext, DiagramContext)}. + */ + public List getExposedElements(Element element, Element parent, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext) { + return this.diagramQueryExposeService.getExposedElements(element, parent, domainType, ancestors, editingContext, diagramContext); + } + + /** + * {@link DiagramQueryExposeService#getExposedStakeholders(Element, EClass, List, IEditingContext, DiagramContext)}. + */ + public List getExposedStakeholders(Element element, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext) { + return this.diagramQueryExposeService.getExposedStakeholders(element, domainType, ancestors, editingContext, diagramContext); + } + + /** + * {@link DiagramQueryExposeService#getExposedSubjects(Element, EClass, List, IEditingContext, DiagramContext)}. + */ + public List getExposedSubjects(Element element, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext) { + return this.diagramQueryExposeService.getExposedSubjects(element, domainType, ancestors, editingContext, diagramContext); } /** @@ -139,17 +212,17 @@ public String getMultiplicityLabel(Element element) { } /** - * {@link DiagramQueryLabelService#getTransitionLabel(TransitionUsage)}. + * {@link DiagramQueryLabelService#getSatisfyLabel(SatisfyRequirementUsage)}. */ - public String getTransitionLabel(TransitionUsage transition) { - return this.diagramQueryLabelService.getTransitionLabel(transition); + public String getSatisfyLabel(SatisfyRequirementUsage satisfyRequirementUsage) { + return this.diagramQueryLabelService.getSatisfyLabel(satisfyRequirementUsage); } /** - * {@link DiagramQueryLabelService#getSatisfyLabel(SatisfyRequirementUsage)}. + * {@link DiagramQueryLabelService#getTransitionLabel(TransitionUsage)}. */ - public String getSatisfyLabel(SatisfyRequirementUsage satisfyRequirementUsage) { - return this.diagramQueryLabelService.getSatisfyLabel(satisfyRequirementUsage); + public String getTransitionLabel(TransitionUsage transition) { + return this.diagramQueryLabelService.getTransitionLabel(transition); } /** @@ -167,6 +240,35 @@ public boolean isDiagramEmpty(IEditingContext editingContext, DiagramContext dia return this.diagramQueryElementService.isDiagramEmpty(editingContext, diagramContext, previousDiagram, exposedElements); } + /** + * {@link DiagramQueryViewService#isHiddenByDefault(Element, String, List, IEditingContext, DiagramContext)}. + */ + public boolean isHiddenByDefault(Element self, String compartmentName, List ancestors, IEditingContext editingContext, DiagramContext diagramContext) { + return this.diagramQueryViewService.isHiddenByDefault(self, compartmentName, ancestors, editingContext, diagramContext); + } + + /** + * {@link DiagramQueryGraphicalService#isNotAncestorOf(org.eclipse.sirius.components.representations.Element, org.eclipse.sirius.components.representations.Element, DiagramRenderingCache)}. + */ + public boolean isNotAncestorOf(org.eclipse.sirius.components.representations.Element parentNodeElement, + org.eclipse.sirius.components.representations.Element childNodeElement, DiagramRenderingCache cache) { + return this.diagramQueryGraphicalService.isNotAncestorOf(parentNodeElement, childNodeElement, cache); + } + + /** + * {@link DiagramQueryViewService#isView(Element, String, List, IEditingContext, DiagramContext)}. + */ + public boolean isView(Element element, String viewDefinition, List ancestors, IEditingContext editingContext, DiagramContext diagramContext) { + return this.diagramQueryViewService.isView(element, viewDefinition, ancestors, editingContext, diagramContext); + } + + /** + * {@link DiagramQueryViewService#isView(Element, String, Node, IEditingContext, DiagramContext)}. + */ + public boolean isView(Element element, String viewDefinition, Node selectedNode, IEditingContext editingContext, DiagramContext diagramContext) { + return this.diagramQueryViewService.isView(element, viewDefinition, selectedNode, editingContext, diagramContext); + } + /** * {@link DiagramQueryElementService#shouldRenderConnectorEdge(Connector, org.eclipse.sirius.components.representations.Element, org.eclipse.sirius.components.representations.Element, DiagramRenderingCache, IEditingContext)}. */ @@ -176,9 +278,9 @@ public boolean shouldRenderConnectorEdge(Connector connector, org.eclipse.sirius } /** - * {@link DiagramQueryElementService#canCreateFlowUsage(ConnectionUsage)}. + * {@link DiagramQueryAnnotatingService#showAnnotatingNode(Element, DiagramContext, IEditingContext)}. */ - public boolean canCreateFlowUsage(ConnectionUsage connection) { - return this.diagramQueryElementService.canCreateFlowUsage(connection); + public boolean showAnnotatingNode(Element element, DiagramContext diagramContext, IEditingContext editingContext) { + return this.diagramQueryAnnotatingService.showAnnotatingNode(element, diagramContext, editingContext); } } diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/RevealCompartmentSwitch.java b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/utils/RevealCompartmentSwitch.java similarity index 89% rename from backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/RevealCompartmentSwitch.java rename to backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/utils/RevealCompartmentSwitch.java index 0f9b0a97d..8d6d698d0 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/RevealCompartmentSwitch.java +++ b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/utils/RevealCompartmentSwitch.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2025, 2026 Obeo. + * 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 @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.diagram.common.view.services; +package org.eclipse.syson.diagram.services.utils; import org.eclipse.emf.ecore.EObject; import org.eclipse.syson.sysml.ActionUsage; @@ -27,17 +27,12 @@ import org.eclipse.syson.sysml.util.SysmlSwitch; /** - * Switch allowing to know in which cases a compartment should be revealed. It is used by - * ViewNodeService#revealCompartment(). + * Switch allowing to know in which cases a compartment should be revealed. * * @author arichard */ public class RevealCompartmentSwitch extends SysmlSwitch { - /** - * If the ViewUsage associated to the object on which this Switch is applied is typed by a GeneralView - * ViewDefinition or not. - */ private final boolean isGeneralView; public RevealCompartmentSwitch(boolean isGeneralView) { diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewFilterSwitch.java b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/utils/ViewFilterSwitch.java similarity index 64% rename from backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewFilterSwitch.java rename to backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/utils/ViewFilterSwitch.java index fb5a3ce05..b8b2695a1 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewFilterSwitch.java +++ b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/utils/ViewFilterSwitch.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2025, 2026 Obeo. + * 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 @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.syson.diagram.common.view.services; +package org.eclipse.syson.diagram.services.utils; import java.util.List; import java.util.Objects; @@ -34,46 +34,25 @@ import org.eclipse.syson.sysml.util.SysmlSwitch; /** - * Switch allowing to know in which cases a Node should be displayed or not. - *

- * In General View, a sibling Node and a composition edge should be displayed after the creation of a new nested - * semantic Usage/Definition. - *

- *

- * In Interconnection View, the nested Nodes should not be displayed. They are handled by other NodeDescriptions, inside - * compartments. - *

- *

- * Root elements return true for this switch because the NodeDescriptions calling ViewNodeService#getExposedElements are - * the same for root and nested Nodes. - *

+ * Switch allowing to know in which cases a node should be displayed or not. * * @author arichard */ public class ViewFilterSwitch extends SysmlSwitch { - /** - * The kind of ViewDefinition the ViewUsage associated to the object on which this Switch is applied is typed by. - */ private final ViewDefinitionKind kind; - /** - * The list of exposed Elements associated the ViewUsage associated to the object on which this Switch is applied. - */ private final List exposedElements; - /** - * The parent Element of the object on which this Switch is applied. It can be null. - */ private final Element parentElement; private final MetamodelQueryElementService metamodelQueryElementService; - public ViewFilterSwitch(ViewDefinitionKind kind, List exposedElements, Element parentElement) { + public ViewFilterSwitch(ViewDefinitionKind kind, List exposedElements, Element parentElement, MetamodelQueryElementService metamodelQueryElementService) { this.kind = kind; this.exposedElements = Objects.requireNonNull(exposedElements); this.parentElement = parentElement; - this.metamodelQueryElementService = new MetamodelQueryElementService(); + this.metamodelQueryElementService = Objects.requireNonNull(metamodelQueryElementService); } @Override @@ -93,8 +72,6 @@ public Boolean defaultCase(EObject object) { @Override public Boolean caseAttributeUsage(AttributeUsage object) { - // For AttributeUsages we don't want tree Nodes on InterconnectionView, ActionFlow View or StateTransition - // View. return ViewDefinitionKind.isGeneralView(this.kind); } @@ -106,26 +83,15 @@ public Boolean caseDocumentation(Documentation object) { @Override public Boolean casePackage(Package object) { - // For Packages we don't want nested Nodes, no matter the type of ViewDefinition. return !this.isIndirectNestedNode(object) && !ViewDefinitionKind.isActionFlowView(this.kind) && !ViewDefinitionKind.isStateTransitionView(this.kind); } @Override public Boolean caseReferenceUsage(ReferenceUsage object) { - // For ReferenceUsage we don't want nested Nodes, no matter the type of ViewDefinition. - // The sub ReferenceUsages are displayed in a compartment list called "references" and/or as border nodes. return this.metamodelQueryElementService.isSubject(object) || (!this.isIndirectNestedNode(object) && !ViewDefinitionKind.isActionFlowView(this.kind) && !ViewDefinitionKind.isStateTransitionView(this.kind)); } - /** - * Check if the given object is an indirect nested node of the parentElement of this class. - * - * @param object - * the given object - * @return true if the given object is an indirect node of the parentElement of this class, - * false otherwise. - */ private boolean isIndirectNestedNode(EObject object) { boolean isDirectNestedNode = false; if (this.parentElement instanceof Namespace elt && !elt.getOwnedMember().contains(object)) { @@ -145,14 +111,6 @@ private boolean isIndirectNestedNode(EObject object) { return isDirectNestedNode; } - /** - * Check if the given object is a direct nested node of the parentElement of this class. - * - * @param object - * the given object - * @return true if the given object is a direct nested node of the parentElement of this class, - * false otherwise. - */ private boolean isDirectNestedNode(EObject object) { boolean isDirectNestedNode = false; if (this.parentElement instanceof Namespace elt && elt.getOwnedMember().contains(object)) { @@ -163,22 +121,10 @@ private boolean isDirectNestedNode(EObject object) { return isDirectNestedNode; } - /** - * Check if a sub Package of the given Package contains the given object. - * - * @param pkg - * the given Package - * @param object - * the given object. - * @return true if a sub Package of the given Package contains the given object, false - * otherwise. - */ private boolean subPackageContainsElement(Package pkg, EObject object) { return pkg.getOwnedElement().stream() .filter(Package.class::isInstance) .map(Package.class::cast) - .anyMatch(subPkg -> { - return EMFUtils.isAncestor(subPkg, object); - }); + .anyMatch(subPkg -> EMFUtils.isAncestor(subPkg, object)); } } 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 705468d3d..d5dc33fa7 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2023, 2025 Obeo. + * 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 @@ -24,10 +24,11 @@ import org.eclipse.sirius.components.view.diagram.LineStyle; import org.eclipse.sirius.components.view.diagram.NodeDescription; 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.util.AQLConstants; -import org.eclipse.syson.util.AQLUtils; +import org.eclipse.syson.util.ServiceMethod; import org.eclipse.syson.util.SysMLMetamodelHelper; import org.eclipse.syson.util.ViewConstants; @@ -111,13 +112,15 @@ private EdgeStyle createEdgeStyle() { @Override protected ChangeContextBuilder getSourceReconnectToolBody() { return this.viewBuilderHelper.newChangeContext() - .expression(AQLUtils.getServiceCallExpression(AQLConstants.EDGE_SEMANTIC_ELEMENT, "reconnectSourceAllocateEdge", AQLConstants.SEMANTIC_RECONNECTION_TARGET)); + .expression(ServiceMethod.of1(ViewEdgeService::reconnectSourceAllocateEdge) + .aql(AQLConstants.EDGE_SEMANTIC_ELEMENT, AQLConstants.SEMANTIC_RECONNECTION_TARGET)); } @Override protected ChangeContextBuilder getTargetReconnectToolBody() { return this.viewBuilderHelper.newChangeContext() - .expression(AQLUtils.getServiceCallExpression(AQLConstants.EDGE_SEMANTIC_ELEMENT, "reconnectTargetAllocateEdge", AQLConstants.SEMANTIC_RECONNECTION_TARGET)); + .expression(ServiceMethod.of1(ViewEdgeService::reconnectTargetAllocateEdge) + .aql(AQLConstants.EDGE_SEMANTIC_ELEMENT, AQLConstants.SEMANTIC_RECONNECTION_TARGET)); } } diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractDefinitionOwnedUsageEdgeDescriptionProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractDefinitionOwnedUsageEdgeDescriptionProvider.java index 407ee0996..6c5d39088 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractDefinitionOwnedUsageEdgeDescriptionProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractDefinitionOwnedUsageEdgeDescriptionProvider.java @@ -30,10 +30,10 @@ import org.eclipse.sirius.components.view.diagram.LineStyle; import org.eclipse.sirius.components.view.diagram.NodeDescription; import org.eclipse.sirius.components.view.diagram.SynchronizationPolicy; +import org.eclipse.syson.diagram.common.view.services.ViewToolService; import org.eclipse.syson.diagram.services.aql.DiagramMutationAQLService; import org.eclipse.syson.diagram.services.aql.DiagramQueryAQLService; import org.eclipse.syson.util.AQLConstants; -import org.eclipse.syson.util.AQLUtils; import org.eclipse.syson.util.IDescriptionNameGenerator; import org.eclipse.syson.util.ServiceMethod; import org.eclipse.syson.util.SysMLMetamodelHelper; @@ -79,8 +79,10 @@ public EdgeDescription create() { .style(this.createEdgeStyle()) .synchronizationPolicy(SynchronizationPolicy.SYNCHRONIZED) .targetExpression(AQLConstants.AQL_SELF + "." + this.eReference.getName()) - .preconditionExpression(AQLConstants.AQL + "not " + org.eclipse.sirius.components.diagrams.description.EdgeDescription.GRAPHICAL_EDGE_SOURCE + ".isAncestorOf(" - + org.eclipse.sirius.components.diagrams.description.EdgeDescription.GRAPHICAL_EDGE_TARGET + "," + "cache" + ")") + .preconditionExpression(ServiceMethod.of2(DiagramQueryAQLService::isNotAncestorOf) + .aql(org.eclipse.sirius.components.diagrams.description.EdgeDescription.GRAPHICAL_EDGE_SOURCE, + org.eclipse.sirius.components.diagrams.description.EdgeDescription.GRAPHICAL_EDGE_TARGET, + "cache")) .build(); } @@ -112,7 +114,7 @@ protected boolean isDeletable() { @Override protected DeleteTool getEdgeDeleteTool() { var changeContext = this.viewBuilderHelper.newChangeContext() - .expression(AQLUtils.getServiceCallExpression("semanticEdgeTarget", "moveToClosestContainingPackage")); + .expression(ServiceMethod.of0(ViewToolService::moveToClosestContainingPackage).aql(org.eclipse.sirius.components.diagrams.description.EdgeDescription.SEMANTIC_EDGE_TARGET)); return this.diagramBuilderHelper.newDeleteTool() .name("Delete from Model") diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractSuccessionEdgeDescriptionProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractSuccessionEdgeDescriptionProvider.java index af8157725..ee5577555 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractSuccessionEdgeDescriptionProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractSuccessionEdgeDescriptionProvider.java @@ -25,13 +25,13 @@ import org.eclipse.sirius.components.view.diagram.LineStyle; import org.eclipse.sirius.components.view.diagram.NodeDescription; import org.eclipse.sirius.components.view.diagram.SynchronizationPolicy; +import org.eclipse.syson.diagram.common.view.services.ViewEdgeService; import org.eclipse.syson.diagram.services.aql.DiagramMutationAQLService; import org.eclipse.syson.diagram.services.aql.DiagramQueryAQLService; import org.eclipse.syson.model.services.aql.ModelQueryAQLService; import org.eclipse.syson.services.UtilService; import org.eclipse.syson.sysml.SysmlPackage; import org.eclipse.syson.util.AQLConstants; -import org.eclipse.syson.util.AQLUtils; import org.eclipse.syson.util.IDescriptionNameGenerator; import org.eclipse.syson.util.ServiceMethod; import org.eclipse.syson.util.SysMLMetamodelHelper; @@ -100,16 +100,16 @@ public void link(DiagramDescription diagramDescription, IViewDiagramElementFinde @Override protected ChangeContextBuilder getSourceReconnectToolBody() { - var params = List.of(AQLConstants.SEMANTIC_RECONNECTION_SOURCE, AQLConstants.SEMANTIC_RECONNECTION_TARGET); return this.viewBuilderHelper.newChangeContext() - .expression(AQLUtils.getServiceCallExpression(AQLConstants.EDGE_SEMANTIC_ELEMENT, "reconnectSourceSuccessionEdge", params)); + .expression(ServiceMethod.of2(ViewEdgeService::reconnectSourceSuccessionEdge) + .aql(AQLConstants.EDGE_SEMANTIC_ELEMENT, AQLConstants.SEMANTIC_RECONNECTION_SOURCE, AQLConstants.SEMANTIC_RECONNECTION_TARGET)); } @Override protected ChangeContextBuilder getTargetReconnectToolBody() { - var params = List.of(AQLConstants.SEMANTIC_RECONNECTION_SOURCE, AQLConstants.SEMANTIC_RECONNECTION_TARGET); return this.viewBuilderHelper.newChangeContext() - .expression(AQLUtils.getServiceCallExpression(AQLConstants.EDGE_SEMANTIC_ELEMENT, "reconnectTargetSuccessionEdge", params)); + .expression(ServiceMethod.of2(ViewEdgeService::reconnectTargetSuccessionEdge) + .aql(AQLConstants.EDGE_SEMANTIC_ELEMENT, AQLConstants.SEMANTIC_RECONNECTION_SOURCE, AQLConstants.SEMANTIC_RECONNECTION_TARGET)); } @Override diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractUsageNestedUsageEdgeDescriptionProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractUsageNestedUsageEdgeDescriptionProvider.java index 60b4a4ade..d51f2b6fd 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractUsageNestedUsageEdgeDescriptionProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractUsageNestedUsageEdgeDescriptionProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2023, 2025 Obeo. + * 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 @@ -31,6 +31,7 @@ import org.eclipse.sirius.components.view.diagram.LineStyle; import org.eclipse.sirius.components.view.diagram.NodeDescription; import org.eclipse.sirius.components.view.diagram.SynchronizationPolicy; +import org.eclipse.syson.diagram.common.view.services.ViewToolService; import org.eclipse.syson.diagram.services.aql.DiagramMutationAQLService; import org.eclipse.syson.diagram.services.aql.DiagramQueryAQLService; import org.eclipse.syson.util.AQLConstants; @@ -83,8 +84,10 @@ public EdgeDescription create() { .conditionalStyles(this.createReferenceConditionalEdgeStyle()) .synchronizationPolicy(SynchronizationPolicy.SYNCHRONIZED) .targetExpression(AQLConstants.AQL_SELF + "." + this.eReference.getName()) - .preconditionExpression(AQLConstants.AQL + "not " + org.eclipse.sirius.components.diagrams.description.EdgeDescription.GRAPHICAL_EDGE_SOURCE + ".isAncestorOf(" - + org.eclipse.sirius.components.diagrams.description.EdgeDescription.GRAPHICAL_EDGE_TARGET + ", cache)") + .preconditionExpression(ServiceMethod.of2(DiagramQueryAQLService::isNotAncestorOf) + .aql(org.eclipse.sirius.components.diagrams.description.EdgeDescription.GRAPHICAL_EDGE_SOURCE, + org.eclipse.sirius.components.diagrams.description.EdgeDescription.GRAPHICAL_EDGE_TARGET, + "cache")) .build(); } @@ -137,7 +140,7 @@ protected boolean isDeletable() { @Override protected DeleteTool getEdgeDeleteTool() { var changeContext = this.viewBuilderHelper.newChangeContext() - .expression("aql:semanticEdgeTarget.moveToClosestContainingPackage()"); + .expression(ServiceMethod.of0(ViewToolService::moveToClosestContainingPackage).aql(org.eclipse.sirius.components.diagrams.description.EdgeDescription.SEMANTIC_EDGE_TARGET)); return this.diagramBuilderHelper.newDeleteTool() .name("Delete from Model") diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AnnotationEdgeDescriptionProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AnnotationEdgeDescriptionProvider.java index 1eafa2ac0..f0a426f75 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AnnotationEdgeDescriptionProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AnnotationEdgeDescriptionProvider.java @@ -26,10 +26,10 @@ import org.eclipse.sirius.components.view.diagram.LineStyle; import org.eclipse.sirius.components.view.diagram.NodeDescription; import org.eclipse.sirius.components.view.diagram.SynchronizationPolicy; +import org.eclipse.syson.diagram.common.view.services.ViewToolService; import org.eclipse.syson.services.UtilService; import org.eclipse.syson.sysml.SysmlPackage; import org.eclipse.syson.util.AQLConstants; -import org.eclipse.syson.util.AQLUtils; import org.eclipse.syson.util.IDescriptionNameGenerator; import org.eclipse.syson.util.ServiceMethod; import org.eclipse.syson.util.SysMLMetamodelHelper; @@ -108,7 +108,8 @@ protected ChangeContextBuilder getSourceReconnectToolBody() { @Override protected ChangeContextBuilder getTargetReconnectToolBody() { return this.viewBuilderHelper.newChangeContext() - .expression(AQLUtils.getServiceCallExpression(AQLConstants.EDGE_SEMANTIC_ELEMENT, "reconnnectTargetAnnotatedEdge", AQLConstants.SEMANTIC_RECONNECTION_TARGET)); + .expression(ServiceMethod.of1(ViewToolService::reconnnectTargetAnnotatedEdge) + .aql(AQLConstants.EDGE_SEMANTIC_ELEMENT, AQLConstants.SEMANTIC_RECONNECTION_TARGET)); } /** diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AbstractCompartmentNodeDescriptionProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AbstractCompartmentNodeDescriptionProvider.java index ea6fc12de..8a3fc2a78 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AbstractCompartmentNodeDescriptionProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AbstractCompartmentNodeDescriptionProvider.java @@ -39,10 +39,10 @@ import org.eclipse.sirius.components.view.diagram.SynchronizationPolicy; import org.eclipse.sirius.components.view.diagram.UserResizableDirection; import org.eclipse.sirius.components.view.emf.diagram.ViewDiagramDescriptionConverter; -import org.eclipse.syson.diagram.common.view.services.ViewNodeService; import org.eclipse.syson.diagram.common.view.services.description.ToolDescriptionService; import org.eclipse.syson.diagram.common.view.tools.CompartmentNodeToolProvider; import org.eclipse.syson.diagram.services.aql.DiagramMutationAQLService; +import org.eclipse.syson.diagram.services.aql.DiagramQueryAQLService; import org.eclipse.syson.sysml.SysmlPackage; import org.eclipse.syson.util.AQLConstants; import org.eclipse.syson.util.AQLUtils; @@ -145,7 +145,7 @@ protected List getItemCreationToolProviders() { * false otherwise. */ protected String isHiddenByDefaultExpression() { - return ServiceMethod.of4(ViewNodeService::isHiddenByDefault).aqlSelf(AQLUtils.aqlString(this.getCompartmentName()), + return ServiceMethod.of4(DiagramQueryAQLService::isHiddenByDefault).aqlSelf(AQLUtils.aqlString(this.getCompartmentName()), org.eclipse.sirius.components.diagrams.description.NodeDescription.ANCESTORS, IEditingContext.EDITING_CONTEXT, DiagramContext.DIAGRAM_CONTEXT); } diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AbstractControlNodeActionNodeDescriptionProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AbstractControlNodeActionNodeDescriptionProvider.java index 670902994..eb8cafb55 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AbstractControlNodeActionNodeDescriptionProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AbstractControlNodeActionNodeDescriptionProvider.java @@ -12,6 +12,8 @@ *******************************************************************************/ package org.eclipse.syson.diagram.common.view.nodes; +import static org.eclipse.sirius.components.diagrams.description.NodeDescription.ANCESTORS; + import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -35,8 +37,8 @@ import org.eclipse.syson.diagram.services.aql.DiagramMutationAQLService; import org.eclipse.syson.diagram.services.aql.DiagramQueryAQLService; import org.eclipse.syson.services.DeleteService; +import org.eclipse.syson.sysml.Element; import org.eclipse.syson.util.AQLConstants; -import org.eclipse.syson.util.AQLUtils; import org.eclipse.syson.util.IDescriptionNameGenerator; import org.eclipse.syson.util.ServiceMethod; import org.eclipse.syson.util.SysMLMetamodelHelper; @@ -99,8 +101,10 @@ public NodeDescription create() { .defaultHeightExpression(this.getDefaultHeightExpression()) .outsideLabels(this.createOutsideLabelDescription()) .name(this.descriptionNameGenerator.getNodeName(this.getNodeDescriptionName())) - .semanticCandidatesExpression(AQLUtils.getSelfServiceCallExpression("getExposedElements", - List.of(domainType, org.eclipse.sirius.components.diagrams.description.NodeDescription.ANCESTORS, IEditingContext.EDITING_CONTEXT, DiagramContext.DIAGRAM_CONTEXT))) + .semanticCandidatesExpression(ServiceMethod.of4(DiagramQueryAQLService.class, + DiagramQueryAQLService::getExposedElements, Element.class, EClass.class, List.class, + IEditingContext.class, DiagramContext.class) + .aqlSelf(domainType, ANCESTORS, IEditingContext.EDITING_CONTEXT, DiagramContext.DIAGRAM_CONTEXT)) .style(this.createNodeStyleDescription()) .userResizable(this.isNodeResizable()) .synchronizationPolicy(SynchronizationPolicy.SYNCHRONIZED) diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AbstractNodeDescriptionProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AbstractNodeDescriptionProvider.java index 8ccd8cbcd..01c138d91 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AbstractNodeDescriptionProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AbstractNodeDescriptionProvider.java @@ -31,6 +31,8 @@ import org.eclipse.sirius.components.view.diagram.provider.DefaultToolsFactory; import org.eclipse.sirius.components.view.emf.diagram.ViewDiagramDescriptionConverter; import org.eclipse.syson.diagram.services.aql.DiagramMutationAQLService; +import org.eclipse.syson.diagram.services.aql.DiagramQueryAQLService; +import org.eclipse.syson.sysml.Element; import org.eclipse.syson.util.AQLConstants; import org.eclipse.syson.util.AQLUtils; import org.eclipse.syson.util.ServiceMethod; @@ -113,8 +115,9 @@ protected NodeTool getShowContentAsNestedTool() { return this.diagramBuilderHelper.newNodeTool() .name("Show content as Nested") .iconURLsExpression("/icons/full/obj16/ShowTool.svg") - .preconditionExpression(AQLUtils.getSelfServiceCallExpression("isView", - List.of(AQLUtils.aqlString(StandardDiagramsConstants.GV_QN), Node.SELECTED_NODE, IEditingContext.EDITING_CONTEXT, DiagramContext.DIAGRAM_CONTEXT))) + .preconditionExpression(ServiceMethod.of4(DiagramQueryAQLService.class, DiagramQueryAQLService::isView, + Element.class, String.class, Node.class, IEditingContext.class, DiagramContext.class) + .aqlSelf(AQLUtils.aqlString(StandardDiagramsConstants.GV_QN), Node.SELECTED_NODE, IEditingContext.EDITING_CONTEXT, DiagramContext.DIAGRAM_CONTEXT)) .body(this.diagramBuilderHelper.newDeleteView() .children(this.viewBuilderHelper.newChangeContext() .expression( @@ -128,8 +131,9 @@ protected NodeTool getShowContentAsTreeTool() { return this.diagramBuilderHelper.newNodeTool() .name("Show content as Tree") .iconURLsExpression("/icons/full/obj16/ShowTool.svg") - .preconditionExpression(AQLUtils.getSelfServiceCallExpression("isView", - List.of(AQLUtils.aqlString(StandardDiagramsConstants.GV_QN), Node.SELECTED_NODE, IEditingContext.EDITING_CONTEXT, DiagramContext.DIAGRAM_CONTEXT))) + .preconditionExpression(ServiceMethod.of4(DiagramQueryAQLService.class, DiagramQueryAQLService::isView, + Element.class, String.class, Node.class, IEditingContext.class, DiagramContext.class) + .aqlSelf(AQLUtils.aqlString(StandardDiagramsConstants.GV_QN), Node.SELECTED_NODE, IEditingContext.EDITING_CONTEXT, DiagramContext.DIAGRAM_CONTEXT)) .body(this.diagramBuilderHelper.newDeleteView() .children(this.viewBuilderHelper.newChangeContext() .expression( diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AbstractPackageNodeDescriptionProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AbstractPackageNodeDescriptionProvider.java index 90f1a4daa..bb57bafe8 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AbstractPackageNodeDescriptionProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AbstractPackageNodeDescriptionProvider.java @@ -12,6 +12,8 @@ *******************************************************************************/ package org.eclipse.syson.diagram.common.view.nodes; +import static org.eclipse.sirius.components.diagrams.description.NodeDescription.ANCESTORS; + import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -50,11 +52,11 @@ import org.eclipse.syson.diagram.services.aql.DiagramMutationAQLService; import org.eclipse.syson.diagram.services.aql.DiagramQueryAQLService; import org.eclipse.syson.services.UtilService; +import org.eclipse.syson.sysml.Element; import org.eclipse.syson.sysml.SysmlPackage; import org.eclipse.syson.sysmlcustomnodes.SysMLCustomnodesFactory; import org.eclipse.syson.sysmlcustomnodes.SysMLPackageNodeStyleDescription; import org.eclipse.syson.util.AQLConstants; -import org.eclipse.syson.util.AQLUtils; import org.eclipse.syson.util.IDescriptionNameGenerator; import org.eclipse.syson.util.ServiceMethod; import org.eclipse.syson.util.SysMLMetamodelHelper; @@ -138,8 +140,10 @@ public NodeDescription create() { .domainType(domainType) .insideLabel(this.createInsideLabelDescription()) .name(this.descriptionNameGenerator.getNodeName(SysmlPackage.eINSTANCE.getPackage())) - .semanticCandidatesExpression(AQLUtils.getSelfServiceCallExpression("getExposedElements", - List.of(domainType, org.eclipse.sirius.components.diagrams.description.NodeDescription.ANCESTORS, IEditingContext.EDITING_CONTEXT, DiagramContext.DIAGRAM_CONTEXT))) + .semanticCandidatesExpression(ServiceMethod.of4(DiagramQueryAQLService.class, + DiagramQueryAQLService::getExposedElements, Element.class, EClass.class, List.class, + IEditingContext.class, DiagramContext.class) + .aqlSelf(domainType, ANCESTORS, IEditingContext.EDITING_CONTEXT, DiagramContext.DIAGRAM_CONTEXT)) .style(this.createPackageNodeStyle()) .userResizable(UserResizableDirection.BOTH) .synchronizationPolicy(SynchronizationPolicy.SYNCHRONIZED) diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AnnotatingNodeDescriptionProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AnnotatingNodeDescriptionProvider.java index 4e96ed81b..87418b67f 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AnnotatingNodeDescriptionProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AnnotatingNodeDescriptionProvider.java @@ -36,7 +36,6 @@ import org.eclipse.sirius.components.view.diagram.SynchronizationPolicy; import org.eclipse.sirius.components.view.diagram.UserResizableDirection; import org.eclipse.syson.diagram.common.view.services.ViewLabelService; -import org.eclipse.syson.diagram.common.view.services.ViewNodeService; import org.eclipse.syson.diagram.services.aql.DiagramMutationAQLService; import org.eclipse.syson.diagram.services.aql.DiagramQueryAQLService; import org.eclipse.syson.services.DeleteService; @@ -81,7 +80,7 @@ public NodeDescription create() { .style(this.createNoteNodeStyle()) .userResizable(UserResizableDirection.BOTH) .synchronizationPolicy(SynchronizationPolicy.UNSYNCHRONIZED) - .preconditionExpression(ServiceMethod.of2(ViewNodeService::showAnnotatingNode).aqlSelf(DiagramContext.DIAGRAM_CONTEXT, IEditingContext.EDITING_CONTEXT)) + .preconditionExpression(ServiceMethod.of2(DiagramQueryAQLService::showAnnotatingNode).aqlSelf(DiagramContext.DIAGRAM_CONTEXT, IEditingContext.EDITING_CONTEXT)) .build(); } diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/InterconnectionCompartmentNodeDescriptionProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/InterconnectionCompartmentNodeDescriptionProvider.java index 7071be9af..b0c36bcef 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/InterconnectionCompartmentNodeDescriptionProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/InterconnectionCompartmentNodeDescriptionProvider.java @@ -12,6 +12,8 @@ *******************************************************************************/ package org.eclipse.syson.diagram.common.view.nodes; +import static org.eclipse.sirius.components.diagrams.description.NodeDescription.ANCESTORS; + import java.util.ArrayList; import java.util.List; @@ -33,9 +35,10 @@ import org.eclipse.sirius.components.view.diagram.NodeToolSection; import org.eclipse.sirius.components.view.diagram.SynchronizationPolicy; import org.eclipse.sirius.components.view.diagram.UserResizableDirection; -import org.eclipse.syson.diagram.common.view.services.ViewNodeService; import org.eclipse.syson.diagram.common.view.services.description.ToolConstants; import org.eclipse.syson.diagram.common.view.tools.ActionFlowCompartmentNodeToolProvider; +import org.eclipse.syson.diagram.services.aql.DiagramQueryAQLService; +import org.eclipse.syson.sysml.Element; import org.eclipse.syson.sysml.SysmlPackage; import org.eclipse.syson.util.AQLConstants; import org.eclipse.syson.util.AQLUtils; @@ -70,11 +73,10 @@ public NodeDescription create() { .insideLabel(this.createInsideLabelDescription()) .isHiddenByDefaultExpression(this.isHiddenByDefaultExpression()) .name(this.compartmentName) - .preconditionExpression( - AQLUtils.getSelfServiceCallExpression("isView", - List.of(AQLUtils.aqlString(StandardDiagramsConstants.IV_QN), org.eclipse.sirius.components.diagrams.description.NodeDescription.ANCESTORS, - IEditingContext.EDITING_CONTEXT, - DiagramContext.DIAGRAM_CONTEXT))) + .preconditionExpression(ServiceMethod.of4(DiagramQueryAQLService.class, DiagramQueryAQLService::isView, Element.class, String.class, List.class, + IEditingContext.class, DiagramContext.class) + .aqlSelf(AQLUtils.aqlString(StandardDiagramsConstants.IV_QN), ANCESTORS, + IEditingContext.EDITING_CONTEXT, DiagramContext.DIAGRAM_CONTEXT)) .semanticCandidatesExpression(AQLConstants.AQL_SELF) .style(this.createCompartmentNodeStyle()) .userResizable(UserResizableDirection.NONE) @@ -168,7 +170,7 @@ protected NodeStyleDescription createCompartmentNodeStyle() { @Override protected String isHiddenByDefaultExpression() { - return ServiceMethod.of4(ViewNodeService::isHiddenByDefault).aqlSelf(AQLUtils.aqlString(this.compartmentName), org.eclipse.sirius.components.diagrams.description.NodeDescription.ANCESTORS, + return ServiceMethod.of4(DiagramQueryAQLService::isHiddenByDefault).aqlSelf(AQLUtils.aqlString(this.compartmentName), ANCESTORS, IEditingContext.EDITING_CONTEXT, DiagramContext.DIAGRAM_CONTEXT); } } diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewNodeService.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewNodeService.java deleted file mode 100644 index 5c510d387..000000000 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewNodeService.java +++ /dev/null @@ -1,728 +0,0 @@ -/******************************************************************************* - * 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.diagram.common.view.services; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Stream; - -import org.eclipse.emf.common.util.EList; -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.sirius.components.collaborative.diagrams.DiagramContext; -import org.eclipse.sirius.components.collaborative.diagrams.DiagramService; -import org.eclipse.sirius.components.collaborative.diagrams.DiagramServices; -import org.eclipse.sirius.components.core.api.IEditingContext; -import org.eclipse.sirius.components.core.api.IObjectSearchService; -import org.eclipse.sirius.components.diagrams.Diagram; -import org.eclipse.sirius.components.diagrams.Edge; -import org.eclipse.sirius.components.diagrams.FreeFormLayoutStrategy; -import org.eclipse.sirius.components.diagrams.IDiagramElement; -import org.eclipse.sirius.components.diagrams.ListLayoutStrategy; -import org.eclipse.sirius.components.diagrams.Node; -import org.eclipse.sirius.components.diagrams.ViewModifier; -import org.eclipse.sirius.components.diagrams.description.NodeDescription; -import org.eclipse.sirius.components.diagrams.elements.NodeElementProps; -import org.eclipse.sirius.components.diagrams.renderer.DiagramRenderingCache; -import org.eclipse.syson.services.NodeDescriptionService; -import org.eclipse.syson.services.UtilService; -import org.eclipse.syson.sysml.ActionUsage; -import org.eclipse.syson.sysml.AnnotatingElement; -import org.eclipse.syson.sysml.Element; -import org.eclipse.syson.sysml.Expose; -import org.eclipse.syson.sysml.LibraryPackage; -import org.eclipse.syson.sysml.MembershipExpose; -import org.eclipse.syson.sysml.Package; -import org.eclipse.syson.sysml.PartUsage; -import org.eclipse.syson.sysml.PerformActionUsage; -import org.eclipse.syson.sysml.ReferenceSubsetting; -import org.eclipse.syson.sysml.ReferenceUsage; -import org.eclipse.syson.sysml.SysmlPackage; -import org.eclipse.syson.sysml.Type; -import org.eclipse.syson.sysml.ViewDefinition; -import org.eclipse.syson.sysml.ViewUsage; -import org.eclipse.syson.sysml.helper.EMFUtils; -import org.eclipse.syson.sysml.metamodel.services.MetamodelQueryElementService; -import org.eclipse.syson.sysml.util.ElementUtil; -import org.eclipse.syson.util.NodeFinder; -import org.eclipse.syson.util.StandardDiagramsConstants; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/** - * Node-related Java services used by several diagrams. - * - * @author gdaniel - */ -public class ViewNodeService { - - private final Logger logger = LoggerFactory.getLogger(ViewNodeService.class); - - private final IObjectSearchService objectSearchService; - - private final MetamodelQueryElementService metamodelQueryElementService; - - private final UtilService utilService; - - private final ElementUtil elementUtil; - - public ViewNodeService(IObjectSearchService objectSearchService) { - this.objectSearchService = Objects.requireNonNull(objectSearchService); - this.metamodelQueryElementService = new MetamodelQueryElementService(); - this.utilService = new UtilService(); - this.elementUtil = new ElementUtil(); - } - - /** - * Get the list of elements to expose for a given {@link Element}. - * - * @param element - * the given {@link Element} - * @param domainType - * the {@link EClass} domainType to filter - * @param ancestors - * the list of ancestors of the node (semantic elements corresponding to graphical ancestors). It - * corresponds to a variable accessible from the variable manager. - * @param editingContext - * the {@link IEditingContext} of the node. It corresponds to a variable accessible from the variable - * manager. - * @param diagramContext - * the {@link DiagramContext} of the node. It corresponds to a variable accessible from the variable - * manager. - * @return - */ - public List getExposedElements(Element element, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext) { - return this.getExposedElements(element, null, domainType, ancestors, editingContext, diagramContext); - } - - /** - * Get the list of elements to expose for a given {@link Element}. - * - * @param element - * the given {@link Element} - * @param element - * the parent element of the given {@link Element} - * @param domainType - * the {@link EClass} domainType to filter - * @param ancestors - * the list of ancestors of the element (semantic elements corresponding to graphical ancestors). It - * corresponds to a variable accessible from the variable manager. - * @param editingContext - * the {@link IEditingContext} of the element. It corresponds to a variable accessible from the variable - * manager. - * @param diagramContext - * the {@link DiagramContext} of the element. It corresponds to a variable accessible from the variable - * manager. - * @return - */ - public List getExposedElements(Element element, Element parent, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext) { - List elementsToExpose = new ArrayList<>(); - if (element instanceof ViewUsage viewUsage) { - var exposedElements = new ArrayList(); - if (parent == null) { - // we only want to display exposed elements that could be displayed as root nodes or nested tree nodes, - // but not nodes that could be displayed inside other nodes - exposedElements.addAll(this.getDirectExposedElements(viewUsage)); - } else { - exposedElements.addAll(viewUsage.getExposedElement()); - } - var filteredExposedElements = exposedElements.stream() - .filter(elt -> this.isTypeOf(elt, domainType) && (parent == null || (!Objects.equals(parent, elt) && EMFUtils.isAncestor(parent, elt)))) - .toList(); - elementsToExpose.addAll(filteredExposedElements); - // if it is not a General View, we don't want to display nested nodes as tree (i.e. sibling nodes + - // composition edges), if it an ActionFlow view, we only want to display Action Nodes as root nodes, ... - var viewDefKind = this.utilService.getViewDefinitionKind(viewUsage, ancestors, editingContext); - for (Element filteredExposedElement : filteredExposedElements) { - boolean canBeDisplayed = new ViewFilterSwitch(viewDefKind, exposedElements, parent).doSwitch(filteredExposedElement); - if (!canBeDisplayed) { - elementsToExpose.remove(filteredExposedElement); - } - } - } else if (ancestors != null) { - // Retrieve ViewUsage exposing the given element - var viewUsageContainingElement = ancestors.stream() - .filter(ViewUsage.class::isInstance) - .map(ViewUsage.class::cast) - .findFirst(); - if (viewUsageContainingElement.isPresent()) { - // expose all elements of this ViewUsage - elementsToExpose.addAll(this.getExposedElements(viewUsageContainingElement.get(), element, domainType, ancestors, editingContext, - diagramContext)); - } - } - return elementsToExpose; - } - - /** - * Check if the given {@link Element} displayed in the given {@link DiagramContext} is of the given - * {@link ViewDefinition}. - * - * @param element - * the given {@link Element}. - * @param viewDefinition - * the {@link ViewDefinition} to check. - * @param ancestors - * the list of ancestors of the element (semantic elements corresponding to graphical ancestors). It - * corresponds to a variable accessible from the variable manager. - * @param editingContext - * the {@link IEditingContext} of the element. It corresponds to a variable accessible from the variable - * manager. - * @param diagramContext - * the {@link DiagramContext} of the element. It corresponds to a variable accessible from the variable - * manager. - * @return true if the given {@link Element} displayed in the given {@link DiagramContext} is of the given - * {@link ViewDefinition}, false otherwise. - */ - public boolean isView(Element element, String viewDefinition, List ancestors, IEditingContext editingContext, DiagramContext diagramContext) { - boolean isView = false; - if (element instanceof ViewUsage viewUsage) { - var types = viewUsage.getType(); - if ((types == null || types.isEmpty()) && Objects.equals(StandardDiagramsConstants.GV_QN, viewDefinition)) { - // a ViewUsage without a ViewDefinition is considered as a GeneralView - isView = true; - } else { - var generalViewViewDef = this.elementUtil.findByNameAndType(viewUsage, viewDefinition, ViewDefinition.class); - Type type = types.get(0); - isView = Objects.equals(type, generalViewViewDef); - } - } else { - // Retrieve ViewUsage exposing the given element - var viewUsageContainingElement = ancestors.stream().filter(ViewUsage.class::isInstance).map(ViewUsage.class::cast).findFirst(); - if (viewUsageContainingElement.isPresent()) { - isView = this.isView(viewUsageContainingElement.get(), viewDefinition, ancestors, editingContext, diagramContext); - } - } - return isView; - } - - /** - * Check if the given {@link Element} displayed in the given {@link DiagramContext} is of the given - * {@link ViewDefinition}. - * - * @param element - * the given {@link Element}. - * @param viewDefinition - * the {@link ViewDefinition} to check. - * @param selectedNode - * the selected node. It corresponds to a variable accessible from the variable manager. - * @param editingContext - * the {@link IEditingContext} of the element. It corresponds to a variable accessible from the variable - * manager. - * @param diagramContext - * the {@link DiagramContext} of the element. It corresponds to a variable accessible from the variable - * manager. - * @return true if the given {@link Element} displayed in the given {@link DiagramContext} is of the given - * {@link ViewDefinition}, false otherwise. - */ - public boolean isView(Element element, String viewDefinition, Node selectedNode, IEditingContext editingContext, DiagramContext diagramContext) { - boolean isView = false; - if (element instanceof ViewUsage viewUsage) { - var types = viewUsage.getType(); - if ((types == null || types.isEmpty()) && Objects.equals(StandardDiagramsConstants.GV_QN, viewDefinition)) { - isView = true; - } else { - var generalViewViewDef = this.elementUtil.findByNameAndType(viewUsage, viewDefinition, ViewDefinition.class); - Type type = types.get(0); - isView = Objects.equals(type, generalViewViewDef); - } - } else { - // Retrieve ViewUsage exposing the given element - var ancestors = this.getAncestors(selectedNode, diagramContext.diagram(), editingContext); - var viewUsageContainingElement = ancestors.stream().filter(ViewUsage.class::isInstance).map(ViewUsage.class::cast).findFirst(); - if (viewUsageContainingElement.isPresent()) { - // expose all elements of this ViewUsage - isView = this.isView(viewUsageContainingElement.get(), viewDefinition, selectedNode, editingContext, diagramContext); - } - } - return isView; - } - - /** - * Reveals the compartment in {@code node} that can display {@code targetElement}. - *

- * Reveals a compartment in {@code node} only if none of the displayed compartment can handle {@code targetElement}. - * If many compartment candidates exist, selects the first free-form compartment. - *

- *

- * This method does not assume that the node representing {@code targetElement} is already displayed on the diagram. - * It looks for the compartment that can (or already does) contain the node, and makes it visible. This means that - * this method can be called as part of the creation process of {@code targetElement}, even if the node representing - * it hasn't been rendered yet (e.g. if the node is synchronized). - *

- * - * @param node - * the node containing the compartments - * @param targetElement - * the semantic element to reveal the compartment of - * @param diagramContext - * the {@link DiagramContext} of the element. It corresponds to a variable accessible from the variable - * manager. - * @param editingContext - * the {@link IEditingContext} of the element. It corresponds to a variable accessible from the variable - * manager. - * @param convertedNodes - * the map of all existing node descriptions in the DiagramDescription of this Diagram. It corresponds to - * a variable accessible from the variable manager. - * @return the node containing the compartments - */ - public Node revealCompartment(Node node, Element targetElement, DiagramContext diagramContext, IEditingContext editingContext, - Map convertedNodes) { - - if (!this.utilService.isUnsynchronized(targetElement) - && !this.needToRevealCompartment(targetElement, this.isView(targetElement, StandardDiagramsConstants.GV_QN, node, editingContext, diagramContext))) { - return node; - } - var nodeDescription = convertedNodes.values().stream() - .filter(nodeDesc -> Objects.equals(nodeDesc.getId(), node.getDescriptionId())) - .findFirst(); - - List allChildNodeDescriptions = nodeDescription.map(nodeDesc -> Stream.concat( - nodeDesc.getChildNodeDescriptions().stream(), - convertedNodes.values().stream().filter(convNode -> nodeDesc.getReusedChildNodeDescriptionIds().contains(convNode.getId()))) - .toList()) - .orElse(List.of()); - - var parentObject = this.objectSearchService.getObject(editingContext, node.getTargetObjectId()).orElse(null); - - NodeDescriptionService nodeDescriptionService = new NodeDescriptionService(this.objectSearchService); - - var compartmentDescriptionCandidates = nodeDescriptionService.getNodeDescriptionsForRenderingElementAsChild(targetElement, parentObject, allChildNodeDescriptions, - convertedNodes, editingContext, diagramContext).stream() - .map(NodeDescription::getId) - .toList(); - - if (!compartmentDescriptionCandidates.isEmpty()) { - NodeFinder nodeFinder = new NodeFinder(diagramContext.diagram()); - List compartmentNodeCandidates = nodeFinder - .getAllNodesMatching(n -> compartmentDescriptionCandidates.stream().anyMatch(id -> Objects.equals(id, n.getDescriptionId())) - && Objects.equals(n.getTargetObjectId(), node.getTargetObjectId()) - ); - var noCompartmentToHandleTargetElement = compartmentNodeCandidates.stream() - .allMatch(candidate -> ViewModifier.Hidden.equals(candidate.getState())); - if (noCompartmentToHandleTargetElement) { - compartmentNodeCandidates.stream().reduce((previousCandidate, newCandidate) -> { - if (previousCandidate.getStyle().getChildrenLayoutStrategy() instanceof ListLayoutStrategy && newCandidate.getStyle().getChildrenLayoutStrategy() instanceof FreeFormLayoutStrategy) { - return newCandidate; - } - return previousCandidate; - }).ifPresent(compartmentToReveal -> new DiagramServices().reveal(new DiagramService(diagramContext), List.of(compartmentToReveal))); - } - } - return node; - } - - /** - * Check if the compartment associated to the given {@link Element} should be hidden by default. - * - * @param self - * the {@link Element} associated to the compartment node. - * @param compartmentName - * the name of the compartment to display/hide by default - * @param ancestors - * the list of ancestors of the element (semantic elements corresponding to graphical ancestors). It - * corresponds to a variable accessible from the variable manager. - * @param editingContext - * the {@link IEditingContext} of the element. It corresponds to a variable accessible from the variable - * manager. - * @param diagramContext - * the {@link DiagramContext} of the element. It corresponds to a variable accessible from the variable - * manager. - * @return true if the compartment should be hidden by default, false otherwise - */ - public boolean isHiddenByDefault(Element self, String compartmentName, List ancestors, IEditingContext editingContext, DiagramContext diagramContext) { - boolean isHiddenByDefault = true; - // @technical-debt we should find a way to compute this compartment name here and in - // InterconnectionCompartmentNodeDescriptionProvider only once. - if ("GV Compartment interconnection FreeForm".equals(compartmentName)) { - var exposedParts = this.getExposedElements(self, SysmlPackage.eINSTANCE.getPartUsage(), ancestors, editingContext, diagramContext); - var exposedActions = this.getExposedElements(self, SysmlPackage.eINSTANCE.getActionUsage(), ancestors, editingContext, diagramContext); - var exposedSatisfyRequirements = this.getExposedElements(self, SysmlPackage.eINSTANCE.getSatisfyRequirementUsage(), ancestors, editingContext, diagramContext); - if (!exposedParts.isEmpty() || !exposedActions.isEmpty() || !exposedSatisfyRequirements.isEmpty()) { - isHiddenByDefault = false; - } - } - return isHiddenByDefault; - } - - /** - * Returns {@code true} if {@code parentNodeElement} is an ancestor of {@code childNodeElement}. - *

- * This method checks if {@code parentNodeElement} contains (directly or indirectly) {@code childNodeElement} in the - * provided {@code diagramContext}. It is typically called in edge preconditions to prevent the creation of - * containment edges that are not necessary because the node is graphically contained in its parent. - *

- * - * @param parentNodeElement - * the element representing the parent node - * @param childNodeElement - * the element representing the child node - * @param cache - * the rendering cache used in the current rendering process - * @return {@code true} if {@code parentNodeElement} is an ancestor of {@code childNodeElement} - */ - public boolean isAncestorOf(org.eclipse.sirius.components.representations.Element parentNodeElement, org.eclipse.sirius.components.representations.Element childNodeElement, - DiagramRenderingCache cache) { - boolean result = false; - if (parentNodeElement.getProps() instanceof NodeElementProps parentNodeProps - && childNodeElement.getProps() instanceof NodeElementProps childNodeProps) { - List ancestorIds = cache.getAncestors(childNodeProps.getId()).stream() - .map(org.eclipse.sirius.components.representations.Element::getProps) - .filter(NodeElementProps.class::isInstance) - .map(NodeElementProps.class::cast) - .map(NodeElementProps::getId) - .toList(); - result = ancestorIds.contains(parentNodeProps.getId()); - } else { - this.logger.warn("Cannot check graphical containment between {} and {}", parentNodeElement, childNodeElement); - } - return result; - } - - /** - * Get all Actors ({@link PartUsage}) in {@link ViewUsage}'s exposed elements. - * - * @param element - * the {@link Element} for which we want the Actors. - * @param domainType - * the domain type to the elements to retrieve - * @param ancestors - * the given ancestors (semantic elements of the graphical nodes that are the ancestors) of the Node on - * which this service has been called. - * @param editingContext - * the given {@link IEditingContext} in which this service has been called. - * @param diagramContext - * the given {@link DiagramContext} in which this service has been called. - * @return the list of Actor {@link PartUsage}s in {@link ViewUsage}'s exposed elements. - */ - public List getExposedActors(Element element, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext) { - return this.getExposedElements(element, domainType, ancestors, editingContext, diagramContext).stream() - .filter(PartUsage.class::isInstance) - .map(PartUsage.class::cast) - .filter(this.metamodelQueryElementService::isActor) - .toList(); - } - - /** - * Get all Stakeholder ({@link PartUsage}) in {@link ViewUsage}'s exposed elements. - * - * @param element - * the {@link Element} for which we want the Stakeholders. - * @param domainType - * the domain type to the elements to retrieve - * @param ancestors - * the given ancestors (semantic elements of the graphical nodes that are the ancestors) of the Node on - * which this service has been called. - * @param editingContext - * the given {@link IEditingContext} in which this service has been called. - * @param diagramContext - * the given {@link DiagramContext} in which this service has been called. - * @return the list of Actor {@link PartUsage}s in {@link ViewUsage}'s exposed elements. - */ - public List getExposedStakeholders(Element element, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext) { - return this.getExposedElements(element, domainType, ancestors, editingContext, diagramContext).stream() - .filter(PartUsage.class::isInstance) - .map(PartUsage.class::cast) - .filter(this.metamodelQueryElementService::isStakeholder) - .toList(); - } - - /** - * Get all Subjects ({@link ReferenceUsage}) in {@link ViewUsage}'s exposed elements. - * - * @param element - * the {@link Element} for which we want the Actors. - * @param domainType - * the domain type to the elements to retrieve - * @param ancestors - * the given ancestors (semantic elements of the graphical nodes that are the ancestors) of the Node on - * which this service has been called. - * @param editingContext - * the given {@link IEditingContext} in which this service has been called. - * @param diagramContext - * the given {@link DiagramContext} in which this service has been called. - * @return the list of Subject {@link ReferenceUsage}s in {@link ViewUsage}'s exposed elements. - */ - public List getExposedSubjects(Element element, EClass domainType, List ancestors, IEditingContext editingContext, DiagramContext diagramContext) { - return this.getExposedElements(element, domainType, ancestors, editingContext, diagramContext).stream() - .filter(ReferenceUsage.class::isInstance) - .map(ReferenceUsage.class::cast) - .filter(this.metamodelQueryElementService::isSubject) - .toList(); - } - - public List getAllReachableRequirements(EObject eObject) { - List allRequirementUsages = this.utilService.getAllReachableType(eObject, SysmlPackage.eINSTANCE.getRequirementUsage(), false); - List allRequirementDefinitions = this.utilService.getAllReachableType(eObject, SysmlPackage.eINSTANCE.getRequirementDefinition(), false); - return Stream.concat(allRequirementUsages.stream(), allRequirementDefinitions.stream()) - .filter(Element.class::isInstance) - .map(Element.class::cast) - .toList(); - } - - /** - * Returns {@code true} if the provided annotated element of the given {@code element} is represented on the - * diagram, {@code false} otherwise. - * - * @param element - * the element to check - * @param diagramContext - * the diagram context - * @param editingContext - * the editing context - * @return {@code true} if the provided annotated element of {@code element} is represented on the diagram, - * {@code false} otherwise - */ - public boolean showAnnotatingNode(Element element, DiagramContext diagramContext, IEditingContext editingContext) { - boolean displayAnnotatingNode = false; - if (element instanceof AnnotatingElement ae && diagramContext != null && editingContext != null) { - EList annotatedElements = ae.getAnnotatedElement(); - IDiagramElement matchingDiagramElement = null; - - // specific case of an AnnotatingNode related to the ViewUsage corresponding to the diagram or the container - // of the ViewUsage. - displayAnnotatingNode = this.isAnnotatingNodeOnRoot(diagramContext, editingContext, annotatedElements); - - if (!displayAnnotatingNode) { - for (Node node : diagramContext.diagram().getNodes()) { - matchingDiagramElement = this.getOneMatchingAnnotatedNode(node, annotatedElements, diagramContext, editingContext); - if (matchingDiagramElement != null) { - displayAnnotatingNode = true; - break; - } - } - } - if (!displayAnnotatingNode) { - for (Edge edge : diagramContext.diagram().getEdges()) { - matchingDiagramElement = this.getOneMatchingAnnotatedEdge(edge, annotatedElements, diagramContext, editingContext); - if (matchingDiagramElement != null) { - displayAnnotatingNode = true; - break; - } - } - } - } else { - // drag & drop from explorer view - displayAnnotatingNode = true; - } - return displayAnnotatingNode; - } - - /** - * Get the elements we want to display for a ViewUsage, based on its exposed elements. For example for an exposed - * Package, we do not want to also expose its children. The children of the Package will be display as child node - * inside the Package node. - * - * @param viewUsage - * the given {@link ViewUsage}. - * @return a set of {@link Element}s. - */ - protected Set getDirectExposedElements(ViewUsage viewUsage) { - var directExposedElements = new HashSet(); - List exposedElements = viewUsage.getOwnedRelationship().stream() - .filter(Expose.class::isInstance) - .map(Expose.class::cast) - .toList(); - for (Expose exposedElement : exposedElements) { - Element importedElement = exposedElement.getImportedElement(); - if (importedElement instanceof Package) { - directExposedElements.add(importedElement); - } else if (exposedElement instanceof MembershipExpose membershipExpose) { - var importedMembership = membershipExpose.getImportedMembership(); - if (importedMembership != null) { - var memberElement = importedMembership.getMemberElement(); - if (memberElement != null && !this.isChildOfExposedPackage(memberElement, exposedElements)) { - directExposedElements.add(memberElement); - if (exposedElement.isIsRecursive()) { - directExposedElements.addAll(this.getRecursiveContents(memberElement)); - } - } - } - - } - } - return directExposedElements; - } - - /** - * Check if the given {@link Element} is a child of an exposed Package. In this case, we don't want to display it on - * the diagram background, or as a ViewUsage child node. It will be displayed inside another node. - * - * @param element - * the element that could be a child of an exposed element - * @param exposedElements - * the list of exposed elements - * @return true if the given {@link Element} is a child of an exposed element, false - * otherwise. - */ - protected boolean isChildOfExposedPackage(Element element, List exposedElements) { - boolean isChildOfExposedElement = false; - for (Expose exposedElement : exposedElements) { - Element importedElement = exposedElement.getImportedElement(); - if (importedElement instanceof Package && !Objects.equals(element, importedElement) && EMFUtils.isAncestor(importedElement, element)) { - isChildOfExposedElement = true; - break; - } - } - return isChildOfExposedElement; - } - - protected List getRecursiveContents(Element element) { - var contents = new ArrayList(); - var ownedElements = element.getOwnedElement().stream().filter(Objects::nonNull).toList(); - contents.addAll(ownedElements); - ownedElements.forEach(oe -> { - contents.addAll(this.getRecursiveContents(oe)); - }); - return contents; - } - - protected boolean isAnnotatingNodeOnRoot(DiagramContext diagramContext, IEditingContext editingContext, EList annotatedElements) { - boolean isAnnotatingNodeOnRoot = false; - String diagramTargetObjectId = diagramContext.diagram().getTargetObjectId(); - Element diagramTargetObject = this.objectSearchService.getObject(editingContext, diagramTargetObjectId).stream() - .filter(Element.class::isInstance) - .map(Element.class::cast) - .findFirst() - .orElse(null); - if (diagramTargetObject instanceof ViewUsage viewUsage) { - if (annotatedElements.contains(viewUsage)) { - isAnnotatingNodeOnRoot = true; - } else { - isAnnotatingNodeOnRoot = annotatedElements.contains(viewUsage.getOwner()); - } - } - return isAnnotatingNodeOnRoot; - } - - protected boolean isReferencingPerformActionUsage(PerformActionUsage pau) { - // the given PerformActionUsage is a referencing PerformActionUsage if it contains a reference subsetting - // pointing to an action. - ReferenceSubsetting referenceSubSetting = pau.getOwnedReferenceSubsetting(); - return referenceSubSetting != null && referenceSubSetting.getReferencedFeature() instanceof ActionUsage; - } - - protected Edge getOneMatchingAnnotatedEdge(Edge edge, List annotatedElements, DiagramContext diagramContext, IEditingContext editingContext) { - Edge matchingAnnotatedEdge = null; - Optional semanticNodeOpt = this.objectSearchService.getObject(editingContext, edge.getTargetObjectId()); - if (semanticNodeOpt.isPresent()) { - if (annotatedElements.contains(semanticNodeOpt.get())) { - boolean isDeletingAnnotatingEdge = diagramContext.viewDeletionRequests().stream() - .anyMatch(viewDeletionRequest -> Objects.equals(viewDeletionRequest.getElementId(), edge.getId())); - if (!isDeletingAnnotatingEdge) { - // annotating edge is present and it is not planned to be removed - matchingAnnotatedEdge = edge; - } - // Do not browse children of annotating edge which is planned to be removed - return matchingAnnotatedEdge; - } - } - return matchingAnnotatedEdge; - } - - protected Node getOneMatchingAnnotatedNode(Node node, List annotatedElements, DiagramContext diagramContext, IEditingContext editingContext) { - Node matchingAnnotatedNode = null; - Optional semanticNodeOpt = this.objectSearchService.getObject(editingContext, node.getTargetObjectId()); - if (semanticNodeOpt.isPresent()) { - if (annotatedElements.contains(semanticNodeOpt.get())) { - boolean isDeletingAnnotatingNode = diagramContext.viewDeletionRequests().stream() - .anyMatch(viewDeletionRequest -> Objects.equals(viewDeletionRequest.getElementId(), node.getId())); - if (!isDeletingAnnotatingNode) { - // annotating node is present and it is not planned to be removed - matchingAnnotatedNode = node; - } - // Do not browse children of annotating node which is planned to be removed - return matchingAnnotatedNode; - } - } - matchingAnnotatedNode = this.getFirstMatchingChildAnnotatedNode(node, annotatedElements, diagramContext, editingContext); - return matchingAnnotatedNode; - } - - protected Node getFirstMatchingChildAnnotatedNode(Node node, List annotatedElements, DiagramContext diagramContext, IEditingContext editingContext) { - List childrenNodes = Stream.concat(node.getChildNodes().stream(), node.getBorderNodes().stream()).toList(); - for (Node childNode : childrenNodes) { - Node matchingChildAnnotatedNode = this.getOneMatchingAnnotatedNode(childNode, annotatedElements, diagramContext, editingContext); - if (matchingChildAnnotatedNode != null) { - return matchingChildAnnotatedNode; - } - } - return null; - } - - /** - * Check if the compartment associated to the given new {@link Element} created should be revealed or not. - * - * @param element - * the given new {@link Element} - * @param isGeneralView - * if the ViewDefinition in which this new element will be displayed is a GeneralView or not. - * @return true if the compartment need to be revealed, false otherwise. - */ - protected boolean needToRevealCompartment(Element element, boolean isGeneralView) { - return new RevealCompartmentSwitch(isGeneralView).doSwitch(element); - } - - /** - * Get the list of ancestors of the element (semantic elements corresponding to graphical ancestors). - * - * @param selectedNode - * the selected Node. It corresponds to a variable accessible from the variable manager. - * @param diagram - * the diagram containing the selected Node. - * @param editingContext - * the {@link IEditingContext} of the element. It corresponds to a variable accessible from the variable - * manager. - * @return a list of Objects. - */ - protected List getAncestors(Node selectedNode, Diagram diagram, IEditingContext editingContext) { - var ancestors = new ArrayList<>(); - var parent = new NodeFinder(diagram).getParent(selectedNode); - if (parent instanceof Node parentNode) { - var parentObject = this.objectSearchService.getObject(editingContext, parentNode.getTargetObjectId()); - if (parentObject.isPresent()) { - ancestors.add(parentObject.get()); - ancestors.addAll(this.getAncestors(parentNode, diagram, editingContext)); - } - } else if (parent instanceof Diagram) { - var parentObject = this.objectSearchService.getObject(editingContext, diagram.getTargetObjectId()); - if (parentObject.isPresent()) { - ancestors.add(parentObject.get()); - } - } - return ancestors; - } - - /** - * Check if the given {@link Element}'s {@link EClass} is the same than the given domainType. - * - * @param element - * the given {@link Element}. - * @param domainType - * the given domainType as an {@link EClass}. - * @return true if the given {@link Element}'s {@link EClass} is the same than the given domainType, - * false otherwise. - */ - protected boolean isTypeOf(Element element, EClass domainType) { - if (element instanceof LibraryPackage) { - return Objects.equals(SysmlPackage.eINSTANCE.getPackage(), domainType); - } - return element != null && Objects.equals(element.eClass(), domainType); - } -} diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/description/ToolDescriptionService.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/description/ToolDescriptionService.java index 7ab0a70f6..d57610c2d 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/description/ToolDescriptionService.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/description/ToolDescriptionService.java @@ -32,6 +32,7 @@ import org.eclipse.sirius.components.view.diagram.NodeTool; import org.eclipse.sirius.components.view.diagram.NodeToolSection; import org.eclipse.sirius.components.view.emf.diagram.ViewDiagramDescriptionConverter; +import org.eclipse.syson.diagram.common.view.services.ViewCreateService; import org.eclipse.syson.diagram.common.view.services.ViewToolService; import org.eclipse.syson.diagram.services.aql.DiagramMutationAQLService; import org.eclipse.syson.model.services.aql.ModelMutationAQLService; @@ -41,7 +42,6 @@ import org.eclipse.syson.sysml.FeatureMembership; import org.eclipse.syson.sysml.SysmlPackage; import org.eclipse.syson.util.AQLConstants; -import org.eclipse.syson.util.AQLUtils; import org.eclipse.syson.util.IDescriptionNameGenerator; import org.eclipse.syson.util.ServiceMethod; import org.eclipse.syson.util.SysMLMetamodelHelper; @@ -53,8 +53,6 @@ */ public class ToolDescriptionService { - protected static final String SERVICE_ELEMENT_INITIALIZER = "elementInitializer"; - protected static final String NEW_INSTANCE = "newInstance"; protected final ViewBuilders viewBuilderHelper = new ViewBuilders(); @@ -442,7 +440,7 @@ public NodeTool createNodeToolFromDiagramWithDirection(NodeDescription nodeDescr ViewDiagramDescriptionConverter.CONVERTED_NODES_VARIABLE)); var changeContextNewInstance = this.viewBuilderHelper.newChangeContext() - .expression(AQLUtils.getServiceCallExpression(NEW_INSTANCE, SERVICE_ELEMENT_INITIALIZER)); + .expression(ServiceMethod.of0(ViewCreateService::elementInitializer).aql(NEW_INSTANCE)); var createDiagramIfNeeded = this.viewBuilderHelper.newChangeContext() .expression(ServiceMethod.of1(DiagramMutationAQLService::createDiagram).aqlSelf(IEditingContext.EDITING_CONTEXT)); @@ -530,7 +528,7 @@ public NodeTool createNodeToolWithDirection(NodeDescription nodeDescription, ECl ViewDiagramDescriptionConverter.CONVERTED_NODES_VARIABLE)); var changeContextNewInstance = this.viewBuilderHelper.newChangeContext() - .expression(AQLUtils.getServiceCallExpression(NEW_INSTANCE, SERVICE_ELEMENT_INITIALIZER)); + .expression(ServiceMethod.of0(ViewCreateService::elementInitializer).aql(NEW_INSTANCE)); if (direction != null) { changeContextNewInstance.children(setDirection.build(), updateExposedElements.build()); diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/AbstractCompartmentNodeToolProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/AbstractCompartmentNodeToolProvider.java index 54e4278ac..2b39e275a 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/AbstractCompartmentNodeToolProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/AbstractCompartmentNodeToolProvider.java @@ -23,7 +23,6 @@ import org.eclipse.sirius.components.view.diagram.NodeTool; import org.eclipse.sirius.components.view.diagram.SelectionDialogDescription; import org.eclipse.sirius.components.view.emf.diagram.ViewDiagramDescriptionConverter; -import org.eclipse.syson.diagram.common.view.services.ViewNodeService; import org.eclipse.syson.diagram.services.aql.DiagramMutationAQLService; import org.eclipse.syson.util.AQLConstants; import org.eclipse.syson.util.ServiceMethod; @@ -77,7 +76,7 @@ public NodeTool create(IViewDiagramElementFinder cache) { ChangeContextBuilder revealOperation; if (this.revealOnCreate()) { revealOperation = this.viewBuilderHelper.newChangeContext() - .expression(ServiceMethod.of4(ViewNodeService::revealCompartment).aql(Node.SELECTED_NODE, AQLConstants.SELF, DiagramContext.DIAGRAM_CONTEXT, IEditingContext.EDITING_CONTEXT, + .expression(ServiceMethod.of4(DiagramMutationAQLService::revealCompartment).aql(Node.SELECTED_NODE, AQLConstants.SELF, DiagramContext.DIAGRAM_CONTEXT, IEditingContext.EDITING_CONTEXT, ViewDiagramDescriptionConverter.CONVERTED_NODES_VARIABLE)); } else { revealOperation = this.viewBuilderHelper.newChangeContext().expression(AQLConstants.AQL_SELF); diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/AbstractFreeFormCompartmentNodeToolProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/AbstractFreeFormCompartmentNodeToolProvider.java index 7a726c06b..663a72ca1 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/AbstractFreeFormCompartmentNodeToolProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/AbstractFreeFormCompartmentNodeToolProvider.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 @@ -12,7 +12,6 @@ *******************************************************************************/ package org.eclipse.syson.diagram.common.view.tools; -import java.util.List; import java.util.Objects; import org.eclipse.emf.ecore.EClass; @@ -26,7 +25,6 @@ import org.eclipse.sirius.components.view.diagram.NodeTool; import org.eclipse.sirius.components.view.emf.diagram.ViewDiagramDescriptionConverter; import org.eclipse.syson.diagram.services.aql.DiagramMutationAQLService; -import org.eclipse.syson.util.AQLUtils; import org.eclipse.syson.util.IDescriptionNameGenerator; import org.eclipse.syson.util.ServiceMethod; @@ -117,9 +115,8 @@ public NodeTool create(IViewDiagramElementFinder cache) { ViewDiagramDescriptionConverter.CONVERTED_NODES_VARIABLE)); var revealOperation = this.viewBuilderHelper.newChangeContext() - .expression( - AQLUtils.getServiceCallExpression(Node.SELECTED_NODE, "revealCompartment", - List.of("self", DiagramContext.DIAGRAM_CONTEXT, IEditingContext.EDITING_CONTEXT, ViewDiagramDescriptionConverter.CONVERTED_NODES_VARIABLE))); + .expression(ServiceMethod.of4(DiagramMutationAQLService::revealCompartment) + .aql(Node.SELECTED_NODE, "self", DiagramContext.DIAGRAM_CONTEXT, IEditingContext.EDITING_CONTEXT, ViewDiagramDescriptionConverter.CONVERTED_NODES_VARIABLE)); var creationServiceCall = this.viewBuilderHelper.newChangeContext() .expression(this.getCreationServiceCallExpression()) diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ActionFlowCompartmentNodeToolProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ActionFlowCompartmentNodeToolProvider.java index e7aceb7ce..fe8fa5080 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ActionFlowCompartmentNodeToolProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ActionFlowCompartmentNodeToolProvider.java @@ -22,7 +22,6 @@ import org.eclipse.sirius.components.view.diagram.NodeTool; import org.eclipse.sirius.components.view.emf.diagram.ViewDiagramDescriptionConverter; import org.eclipse.syson.diagram.common.view.services.ViewCreateService; -import org.eclipse.syson.diagram.common.view.services.ViewNodeService; import org.eclipse.syson.diagram.services.aql.DiagramMutationAQLService; import org.eclipse.syson.util.AQLConstants; import org.eclipse.syson.util.ServiceMethod; @@ -49,7 +48,7 @@ public NodeTool create(IViewDiagramElementFinder cache) { ViewDiagramDescriptionConverter.CONVERTED_NODES_VARIABLE)); var revealOperation = this.viewBuilderHelper.newChangeContext() - .expression(ServiceMethod.of4(ViewNodeService::revealCompartment).aql(Node.SELECTED_NODE, AQLConstants.SELF, DiagramContext.DIAGRAM_CONTEXT, IEditingContext.EDITING_CONTEXT, + .expression(ServiceMethod.of4(DiagramMutationAQLService::revealCompartment).aql(Node.SELECTED_NODE, AQLConstants.SELF, DiagramContext.DIAGRAM_CONTEXT, IEditingContext.EDITING_CONTEXT, ViewDiagramDescriptionConverter.CONVERTED_NODES_VARIABLE)); var creationServiceCall = this.viewBuilderHelper.newChangeContext() diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ExhibitStateWithReferenceNodeToolProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ExhibitStateWithReferenceNodeToolProvider.java index a402b87a3..c1a8ec718 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ExhibitStateWithReferenceNodeToolProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ExhibitStateWithReferenceNodeToolProvider.java @@ -25,7 +25,6 @@ import org.eclipse.sirius.components.view.diagram.NodeTool; import org.eclipse.sirius.components.view.emf.diagram.ViewDiagramDescriptionConverter; import org.eclipse.syson.diagram.common.view.services.ViewCreateService; -import org.eclipse.syson.diagram.common.view.services.ViewNodeService; import org.eclipse.syson.diagram.common.view.services.ViewToolService; import org.eclipse.syson.diagram.services.aql.DiagramMutationAQLService; import org.eclipse.syson.model.services.aql.ModelMutationAQLService; @@ -83,7 +82,7 @@ public NodeTool create(IViewDiagramElementFinder cache) { .variableName("newInstanceView"); var revealOperation = this.viewBuilderHelper.newChangeContext() - .expression(ServiceMethod.of4(ViewNodeService::revealCompartment).aql(Node.SELECTED_NODE, "newInstance", DiagramContext.DIAGRAM_CONTEXT, IEditingContext.EDITING_CONTEXT, + .expression(ServiceMethod.of4(DiagramMutationAQLService::revealCompartment).aql(Node.SELECTED_NODE, "newInstance", DiagramContext.DIAGRAM_CONTEXT, IEditingContext.EDITING_CONTEXT, ViewDiagramDescriptionConverter.CONVERTED_NODES_VARIABLE)); var updateExposedElements = this.viewBuilderHelper.newChangeContext() diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ObjectiveRequirementWithBaseRequirementCompartmentNodeToolProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ObjectiveRequirementWithBaseRequirementCompartmentNodeToolProvider.java index 2be8ec007..826c7cc40 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ObjectiveRequirementWithBaseRequirementCompartmentNodeToolProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/ObjectiveRequirementWithBaseRequirementCompartmentNodeToolProvider.java @@ -14,7 +14,7 @@ import org.eclipse.sirius.components.view.diagram.SelectionDialogDescription; import org.eclipse.syson.diagram.common.view.services.ViewCreateService; -import org.eclipse.syson.diagram.common.view.services.ViewNodeService; +import org.eclipse.syson.diagram.services.aql.DiagramQueryAQLService; import org.eclipse.syson.sysml.RequirementUsage; import org.eclipse.syson.util.ServiceMethod; @@ -38,7 +38,7 @@ protected String getServiceCallExpression() { @Override protected SelectionDialogDescription getSelectionDialogDescription() { var selectionDialogTree = this.diagramBuilderHelper.newSelectionDialogTreeDescription() - .elementsExpression(ServiceMethod.of0(ViewNodeService::getAllReachableRequirements).aqlSelf()) + .elementsExpression(ServiceMethod.of0(DiagramQueryAQLService::getAllReachableRequirements).aqlSelf()) .build(); return this.diagramBuilderHelper.newSelectionDialogDescription() .selectionDialogTreeDescription(selectionDialogTree) diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/StateSubactionNodeToolProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/StateSubactionNodeToolProvider.java index eb0cbdc90..0ab9d9276 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/StateSubactionNodeToolProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/StateSubactionNodeToolProvider.java @@ -26,8 +26,8 @@ import org.eclipse.sirius.components.view.diagram.NodeTool; import org.eclipse.sirius.components.view.emf.diagram.ViewDiagramDescriptionConverter; import org.eclipse.syson.diagram.common.view.services.ViewCreateService; -import org.eclipse.syson.diagram.common.view.services.ViewNodeService; import org.eclipse.syson.diagram.common.view.services.ViewToolService; +import org.eclipse.syson.diagram.services.aql.DiagramMutationAQLService; import org.eclipse.syson.sysml.StateSubactionKind; import org.eclipse.syson.util.AQLConstants; import org.eclipse.syson.util.AQLUtils; @@ -79,7 +79,7 @@ private String getNodeToolLabel() { private ChangeContext getCreateSubactionOperation() { var revealOperation = this.viewBuilderHelper.newChangeContext() - .expression(ServiceMethod.of4(ViewNodeService::revealCompartment).aql(Node.SELECTED_NODE, AQLConstants.SELF, DiagramContext.DIAGRAM_CONTEXT, IEditingContext.EDITING_CONTEXT, + .expression(ServiceMethod.of4(DiagramMutationAQLService::revealCompartment).aql(Node.SELECTED_NODE, AQLConstants.SELF, DiagramContext.DIAGRAM_CONTEXT, IEditingContext.EDITING_CONTEXT, ViewDiagramDescriptionConverter.CONVERTED_NODES_VARIABLE)); var performedAction = "selectedObject"; diff --git a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/SDVJavaServiceProvider.java b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/SDVJavaServiceProvider.java index f4f946ba4..6b5756628 100644 --- a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/SDVJavaServiceProvider.java +++ b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/SDVJavaServiceProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2023, 2025 Obeo. + * 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 @@ -19,7 +19,6 @@ import org.eclipse.syson.diagram.common.view.services.ViewCreateService; import org.eclipse.syson.diagram.common.view.services.ViewEdgeService; import org.eclipse.syson.diagram.common.view.services.ViewLabelService; -import org.eclipse.syson.diagram.common.view.services.ViewNodeService; import org.eclipse.syson.diagram.common.view.services.ViewToolService; import org.eclipse.syson.diagram.services.aql.DiagramMutationAQLService; import org.eclipse.syson.diagram.services.aql.DiagramQueryAQLService; @@ -51,7 +50,6 @@ public List> getServiceClasses(View view) { ViewEdgeService.class, ViewLabelService.class, ViewToolService.class, - ViewNodeService.class, UtilService.class, DiagramMutationAQLService.class, DiagramQueryAQLService.class, 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 7800bf15c..e8eae7fee 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 @@ -28,12 +28,12 @@ import org.eclipse.sirius.components.view.diagram.NodeDescription; import org.eclipse.sirius.components.view.diagram.SynchronizationPolicy; import org.eclipse.syson.diagram.common.view.edges.AbstractEdgeDescriptionProvider; +import org.eclipse.syson.diagram.common.view.services.ViewEdgeService; 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.util.AQLConstants; -import org.eclipse.syson.util.AQLUtils; import org.eclipse.syson.util.IDescriptionNameGenerator; import org.eclipse.syson.util.ServiceMethod; import org.eclipse.syson.util.SysMLMetamodelHelper; @@ -106,16 +106,16 @@ private EdgeStyle createEdgeStyle() { @Override protected ChangeContextBuilder getSourceReconnectToolBody() { - var params = List.of(AQLConstants.SEMANTIC_RECONNECTION_TARGET); return this.viewBuilderHelper.newChangeContext() - .expression(AQLUtils.getServiceCallExpression(AQLConstants.EDGE_SEMANTIC_ELEMENT, "reconnectSourceIncludeUseCaseUsage", params)); + .expression(ServiceMethod.of1(ViewEdgeService::reconnectSourceIncludeUseCaseUsage) + .aql(AQLConstants.EDGE_SEMANTIC_ELEMENT, AQLConstants.SEMANTIC_RECONNECTION_TARGET)); } @Override protected ChangeContextBuilder getTargetReconnectToolBody() { - var params = List.of(AQLConstants.SEMANTIC_RECONNECTION_TARGET); return this.viewBuilderHelper.newChangeContext() - .expression(AQLUtils.getServiceCallExpression(AQLConstants.EDGE_SEMANTIC_ELEMENT, "reconnectTargetIncludeUseCaseUsage", params)); + .expression(ServiceMethod.of1(ViewEdgeService::reconnectTargetIncludeUseCaseUsage) + .aql(AQLConstants.EDGE_SEMANTIC_ELEMENT, AQLConstants.SEMANTIC_RECONNECTION_TARGET)); } } diff --git a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/ActorNodeDescriptionProvider.java b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/ActorNodeDescriptionProvider.java index cf0583d99..02018cf10 100644 --- a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/ActorNodeDescriptionProvider.java +++ b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/ActorNodeDescriptionProvider.java @@ -29,7 +29,6 @@ import org.eclipse.sirius.components.view.diagram.SynchronizationPolicy; import org.eclipse.sirius.components.view.diagram.UserResizableDirection; import org.eclipse.syson.diagram.common.view.services.ViewLabelService; -import org.eclipse.syson.diagram.common.view.services.ViewNodeService; import org.eclipse.syson.diagram.services.aql.DiagramQueryAQLService; import org.eclipse.syson.model.services.aql.ModelQueryAQLService; import org.eclipse.syson.standard.diagrams.view.SDVDescriptionNameGenerator; @@ -117,7 +116,7 @@ private NodeStyleDescription createActorNodeStyle() { @Override protected String getSemanticCandidatesExpression(String domainType) { - return ServiceMethod.of4(ViewNodeService::getExposedActors).aqlSelf(domainType, org.eclipse.sirius.components.diagrams.description.NodeDescription.ANCESTORS, IEditingContext.EDITING_CONTEXT, + return ServiceMethod.of4(DiagramQueryAQLService::getExposedActors).aqlSelf(domainType, org.eclipse.sirius.components.diagrams.description.NodeDescription.ANCESTORS, IEditingContext.EDITING_CONTEXT, DiagramContext.DIAGRAM_CONTEXT); } diff --git a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/DefinitionNodeDescriptionProvider.java b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/DefinitionNodeDescriptionProvider.java index 4f84b459f..eade01314 100644 --- a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/DefinitionNodeDescriptionProvider.java +++ b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/DefinitionNodeDescriptionProvider.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 @@ -12,6 +12,8 @@ *******************************************************************************/ package org.eclipse.syson.standard.diagrams.view.nodes; +import static org.eclipse.sirius.components.diagrams.description.NodeDescription.ANCESTORS; + import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; @@ -32,12 +34,14 @@ import org.eclipse.syson.diagram.common.view.nodes.JoinActionNodeDescriptionProvider; import org.eclipse.syson.diagram.common.view.nodes.MergeActionNodeDescriptionProvider; import org.eclipse.syson.diagram.common.view.nodes.StartActionNodeDescriptionProvider; +import org.eclipse.syson.diagram.services.aql.DiagramQueryAQLService; import org.eclipse.syson.standard.diagrams.view.SDVDescriptionNameGenerator; import org.eclipse.syson.standard.diagrams.view.SDVDiagramDescriptionProvider; import org.eclipse.syson.standard.diagrams.view.services.SDVNodeToolSectionSwitch; import org.eclipse.syson.standard.diagrams.view.services.SDVNodeToolsWithoutSectionSwitch; +import org.eclipse.syson.sysml.Element; import org.eclipse.syson.sysml.SysmlPackage; -import org.eclipse.syson.util.AQLUtils; +import org.eclipse.syson.util.ServiceMethod; /** * Node description provider for all SysMLv2 Definitions elements in the General View diagram. @@ -52,8 +56,8 @@ public DefinitionNodeDescriptionProvider(EClass eClass, IColorProvider colorProv @Override protected String getSemanticCandidatesExpression(String domainType) { - return AQLUtils.getSelfServiceCallExpression("getExposedElements", - List.of(domainType, org.eclipse.sirius.components.diagrams.description.NodeDescription.ANCESTORS, IEditingContext.EDITING_CONTEXT, DiagramContext.DIAGRAM_CONTEXT)); + return ServiceMethod.of4(DiagramQueryAQLService.class, DiagramQueryAQLService::getExposedElements, Element.class, EClass.class, List.class, IEditingContext.class, DiagramContext.class) + .aqlSelf(domainType, ANCESTORS, IEditingContext.EDITING_CONTEXT, DiagramContext.DIAGRAM_CONTEXT); } @Override diff --git a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/StakeholderNodeDescriptionProvider.java b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/StakeholderNodeDescriptionProvider.java index 93b052a57..1b0351bee 100644 --- a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/StakeholderNodeDescriptionProvider.java +++ b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/StakeholderNodeDescriptionProvider.java @@ -15,7 +15,7 @@ import org.eclipse.sirius.components.collaborative.diagrams.DiagramContext; import org.eclipse.sirius.components.core.api.IEditingContext; import org.eclipse.sirius.components.view.builder.providers.IColorProvider; -import org.eclipse.syson.diagram.common.view.services.ViewNodeService; +import org.eclipse.syson.diagram.services.aql.DiagramQueryAQLService; import org.eclipse.syson.model.services.aql.ModelQueryAQLService; import org.eclipse.syson.standard.diagrams.view.SDVDescriptionNameGenerator; import org.eclipse.syson.sysml.PartUsage; @@ -47,7 +47,7 @@ protected String getNodeDescriptionName() { @Override protected String getSemanticCandidatesExpression(String domainType) { - return ServiceMethod.of4(ViewNodeService::getExposedStakeholders).aqlSelf(domainType, org.eclipse.sirius.components.diagrams.description.NodeDescription.ANCESTORS, + return ServiceMethod.of4(DiagramQueryAQLService::getExposedStakeholders).aqlSelf(domainType, org.eclipse.sirius.components.diagrams.description.NodeDescription.ANCESTORS, IEditingContext.EDITING_CONTEXT, DiagramContext.DIAGRAM_CONTEXT); } diff --git a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/SubjectNodeDescriptionProvider.java b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/SubjectNodeDescriptionProvider.java index d431d480d..a106c5d27 100644 --- a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/SubjectNodeDescriptionProvider.java +++ b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/SubjectNodeDescriptionProvider.java @@ -15,7 +15,7 @@ import org.eclipse.sirius.components.collaborative.diagrams.DiagramContext; import org.eclipse.sirius.components.core.api.IEditingContext; import org.eclipse.sirius.components.view.builder.providers.IColorProvider; -import org.eclipse.syson.diagram.common.view.services.ViewNodeService; +import org.eclipse.syson.diagram.services.aql.DiagramQueryAQLService; import org.eclipse.syson.model.services.aql.ModelQueryAQLService; import org.eclipse.syson.standard.diagrams.view.SDVDescriptionNameGenerator; import org.eclipse.syson.sysml.PartUsage; @@ -47,7 +47,7 @@ protected String getNodeDescriptionName() { @Override protected String getSemanticCandidatesExpression(String domainType) { - return ServiceMethod.of4(ViewNodeService::getExposedSubjects).aqlSelf(domainType, org.eclipse.sirius.components.diagrams.description.NodeDescription.ANCESTORS, IEditingContext.EDITING_CONTEXT, + return ServiceMethod.of4(DiagramQueryAQLService::getExposedSubjects).aqlSelf(domainType, org.eclipse.sirius.components.diagrams.description.NodeDescription.ANCESTORS, IEditingContext.EDITING_CONTEXT, DiagramContext.DIAGRAM_CONTEXT); } } diff --git a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/UsageNodeDescriptionProvider.java b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/UsageNodeDescriptionProvider.java index 68a1aaf03..2e60eff45 100644 --- a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/UsageNodeDescriptionProvider.java +++ b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/UsageNodeDescriptionProvider.java @@ -12,6 +12,8 @@ *******************************************************************************/ package org.eclipse.syson.standard.diagrams.view.nodes; +import static org.eclipse.sirius.components.diagrams.description.NodeDescription.ANCESTORS; + import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; @@ -32,13 +34,15 @@ import org.eclipse.syson.diagram.common.view.nodes.JoinActionNodeDescriptionProvider; import org.eclipse.syson.diagram.common.view.nodes.MergeActionNodeDescriptionProvider; import org.eclipse.syson.diagram.common.view.nodes.StartActionNodeDescriptionProvider; +import org.eclipse.syson.diagram.services.aql.DiagramQueryAQLService; import org.eclipse.syson.standard.diagrams.view.SDVDescriptionNameGenerator; import org.eclipse.syson.standard.diagrams.view.SDVDiagramDescriptionProvider; import org.eclipse.syson.standard.diagrams.view.services.SDVNodeToolSectionSwitch; import org.eclipse.syson.standard.diagrams.view.services.SDVNodeToolsWithoutSectionSwitch; +import org.eclipse.syson.sysml.Element; import org.eclipse.syson.sysml.SysmlPackage; import org.eclipse.syson.util.AQLConstants; -import org.eclipse.syson.util.AQLUtils; +import org.eclipse.syson.util.ServiceMethod; /** * Node description provider for all SysMLv2 Usage elements in the General View diagram. @@ -53,8 +57,8 @@ public UsageNodeDescriptionProvider(EClass eClass, IColorProvider colorProvider) @Override protected String getSemanticCandidatesExpression(String domainType) { - return AQLUtils.getSelfServiceCallExpression("getExposedElements", - List.of(domainType, org.eclipse.sirius.components.diagrams.description.NodeDescription.ANCESTORS, IEditingContext.EDITING_CONTEXT, DiagramContext.DIAGRAM_CONTEXT)); + return ServiceMethod.of4(DiagramQueryAQLService.class, DiagramQueryAQLService::getExposedElements, Element.class, EClass.class, List.class, IEditingContext.class, DiagramContext.class) + .aqlSelf(domainType, ANCESTORS, IEditingContext.EDITING_CONTEXT, DiagramContext.DIAGRAM_CONTEXT); } @Override diff --git a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/ViewUsageNodeDescriptionProvider.java b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/ViewUsageNodeDescriptionProvider.java index b7ff76a2a..038a8f026 100644 --- a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/ViewUsageNodeDescriptionProvider.java +++ b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/ViewUsageNodeDescriptionProvider.java @@ -12,6 +12,8 @@ *******************************************************************************/ package org.eclipse.syson.standard.diagrams.view.nodes; +import static org.eclipse.sirius.components.diagrams.description.NodeDescription.ANCESTORS; + import java.util.ArrayList; import java.util.Comparator; import java.util.List; @@ -54,6 +56,7 @@ import org.eclipse.syson.services.DeleteService; import org.eclipse.syson.services.UtilService; import org.eclipse.syson.standard.diagrams.view.SDVDiagramDescriptionProvider; +import org.eclipse.syson.sysml.Element; import org.eclipse.syson.sysml.SysmlPackage; import org.eclipse.syson.sysmlcustomnodes.SysMLCustomnodesFactory; import org.eclipse.syson.util.AQLUtils; @@ -90,8 +93,10 @@ public NodeDescription create() { .domainType(domainType) .insideLabel(this.createInsideLabelDescription()) .name(this.getNodeDescriptionName()) - .semanticCandidatesExpression(AQLUtils.getSelfServiceCallExpression("getExposedElements", - List.of(domainType, org.eclipse.sirius.components.diagrams.description.NodeDescription.ANCESTORS, IEditingContext.EDITING_CONTEXT, DiagramContext.DIAGRAM_CONTEXT))) + .semanticCandidatesExpression(ServiceMethod.of4(DiagramQueryAQLService.class, + DiagramQueryAQLService::getExposedElements, Element.class, EClass.class, List.class, + IEditingContext.class, DiagramContext.class) + .aqlSelf(domainType, ANCESTORS, IEditingContext.EDITING_CONTEXT, DiagramContext.DIAGRAM_CONTEXT)) .style(this.createViewFrameNodeStyle()) .userResizable(UserResizableDirection.BOTH) .synchronizationPolicy(SynchronizationPolicy.SYNCHRONIZED) diff --git a/scripts/check-coverage.jsh b/scripts/check-coverage.jsh index 5594a0f97..a5db0fc83 100755 --- a/scripts/check-coverage.jsh +++ b/scripts/check-coverage.jsh @@ -35,12 +35,12 @@ var moduleCoverageData = List.of( new ModuleCoverage("syson-application-configuration", 75.0), new ModuleCoverage("syson-common-view", 100.0), new ModuleCoverage("syson-diagram-common-view", 89.0), - new ModuleCoverage("syson-diagram-services", 84.0), + new ModuleCoverage("syson-diagram-services", 85.0), new ModuleCoverage("syson-direct-edit-grammar", 67.0), new ModuleCoverage("syson-form-services", 100.0), new ModuleCoverage("syson-model-services", 94.0), new ModuleCoverage("syson-representation-services", 100.0), - new ModuleCoverage("syson-services", 65.0), + new ModuleCoverage("syson-services", 68.0), new ModuleCoverage("syson-siriusweb-customnodes-metamodel", 41.0), new ModuleCoverage("syson-siriusweb-customnodes-metamodel-edit", 0.0), new ModuleCoverage("syson-standard-diagrams-view", 97.0),