diff --git a/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/FlowNodeService.java b/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/FlowNodeService.java
index 7baddcdc..ddf3bc4e 100644
--- a/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/FlowNodeService.java
+++ b/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/FlowNodeService.java
@@ -22,16 +22,18 @@
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.sirius.diagram.AbstractDNode;
+import org.eclipse.sirius.diagram.DDiagram;
+import org.eclipse.sirius.diagram.DNode;
import org.eclipse.sirius.diagram.description.AbstractNodeMapping;
import org.eclipse.sirius.diagram.description.ContainerMapping;
import org.eclipse.sirius.diagram.description.Layer;
import org.eclipse.sirius.diagram.description.NodeMapping;
+import org.obeonetwork.bpmn2.design.refactoring.SiriusElementRefactor;
import org.obeonetwork.bpmn2.design.ui.PopupChoiceSelector;
import org.obeonetwork.bpmn2.design.ui.UiConstants;
import org.obeonetwork.dsl.bpmn2.Bpmn2Package;
import org.obeonetwork.dsl.bpmn2.Gateway;
-
/**
* Conversion services to operate on FlowNode objects.
*
@@ -39,14 +41,12 @@
*
*/
public class FlowNodeService {
-
+
private static final Bpmn2Package PKG = Bpmn2Package.eINSTANCE;
private static final List GATEWAY_CLASSES = Arrays.asList(
// Order is the same to Gateways Toolsection of VSM
- PKG.getParallelGateway(), PKG.getExclusiveGateway(),
- PKG.getInclusiveGateway(), PKG.getComplexGateway(),
- PKG.getEventBasedGateway()
- );
+ PKG.getParallelGateway(), PKG.getExclusiveGateway(), PKG.getInclusiveGateway(), PKG.getComplexGateway(),
+ PKG.getEventBasedGateway());
/**
* Converts a Gateway into another kind.
@@ -54,7 +54,7 @@ public class FlowNodeService {
* Most of related data are restored.
*
*
- * @param view of Gateway
+ * @param view of Gateway
* @param eClass class to convert in
* @return created Gateway
*/
@@ -63,46 +63,57 @@ public static Gateway convertToSpecificGateway(AbstractDNode view, EClass eClass
if (eClass.equals(previous.eClass())) {
return previous;
}
-
return (Gateway) new SiriusElementRefactor(view) {
@Override
protected boolean isTransferable(EStructuralFeature feature, EClass targetType) {
return Bpmn2Package.eINSTANCE.getBaseElement_Id() != feature;
}
-
+
@Override
protected AbstractNodeMapping getApplicableNodeMapping(AbstractNodeMapping previous, EObject current) {
- // Gateways have several mappings. (For no good reason: only image)
- return current instanceof Gateway
- ? getGatewayMapping(previous.eContainer(), current)
- : previous;
+ // Gateways have several mappings.
+ return current instanceof Gateway ? getGatewayMapping(previous, current) : previous;
+ }
+
+ @Override
+ protected void postCreateNewNode(AbstractDNode newDNode, boolean isExternalLabel) {
+ if (newDNode instanceof DNode && isExternalLabel) {
+ ServiceHelper.setExternalLabel((DNode) newDNode);
+ }
}
}.transformInto(eClass);
}
-
- private static AbstractNodeMapping getGatewayMapping(EObject mappingOwner, EObject target) {
+
+ private static AbstractNodeMapping getGatewayMapping(AbstractNodeMapping previous, EObject target) {
+ if (previous.getName().endsWith("Gateway")) {
+ String classname = "bpmn2." + target.eClass().getName(); // Notation used in ODesign
+ return getMapping(previous.eContainer(), classname);
+ } else {
+ String classname = "bpmn2.BaseElement"; // Notation used in ODesign
+ return getMapping(previous.eContainer(), classname);
+ }
+ }
+
+ private static AbstractNodeMapping getMapping(EObject mappingOwner, String className) {
List siblingMappings = Collections.emptyList();
if (mappingOwner instanceof ContainerMapping) {
siblingMappings = ((ContainerMapping) mappingOwner).getSubNodeMappings();
} else if (mappingOwner instanceof Layer) {
siblingMappings = ((Layer) mappingOwner).getNodeMappings();
}
- String classname = "bpmn2." + target.eClass().getName(); // Notation used in ODesign
for (NodeMapping mapping : siblingMappings) {
- if (Objects.equals(mapping.getDomainClass(), classname)) {
+ if (Objects.equals(mapping.getDomainClass(), className)) {
return mapping;
}
}
return null;
}
-
-
/**
* Applies a function with a type choosen by user.
*
- * @param it context
- * @param types to choose from
+ * @param it context
+ * @param types to choose from
* @param transform to apply
*/
public static T applyToChoosableClass(EObject it, List types, Function transform) {
@@ -118,20 +129,19 @@ public static T applyToChoosableClass(EObject it, List types, Functi
}
return transform.apply(target.get());
}
-
+
/**
* Converts a gateway in a new type.
*
* If no gateway is selected, whole operation is aborted.
*
*
- * @param it gateway to convert
+ * @param it gateway to convert
* @param view on which the task is triggered
* @return new gateway
*/
public static Gateway convertToChoosableGateway(Gateway it, AbstractDNode view) {
- return FlowNodeService.applyToChoosableClass(it, GATEWAY_CLASSES,
- type -> convertToSpecificGateway(view, type));
+ return FlowNodeService.applyToChoosableClass(it, GATEWAY_CLASSES, type -> convertToSpecificGateway(view, type));
}
}
diff --git a/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/ServiceHelper.java b/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/ServiceHelper.java
index 6de831ff..a9a8ea36 100644
--- a/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/ServiceHelper.java
+++ b/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/ServiceHelper.java
@@ -51,7 +51,6 @@
import org.obeonetwork.dsl.bpmn2.SubProcess;
import org.obeonetwork.dsl.bpmn2.Task;
-
/**
* Services for BPMN Viewpoints.
*
@@ -82,7 +81,8 @@ public static ECrossReferenceAdapter getCrossReferenceAdapter(EObject eo) {
/**
* Logs a message with called message.
*
- * This method should only be used will editing VSM. It must be used any released version.
+ * This method should only be used will editing VSM. It must be used any
+ * released version.
*
*
* @param eObject
@@ -113,12 +113,10 @@ public static Definitions getDefinitionsObject(EObject it) {
public static Process getProcess(EObject it) {
return getAncestor(Process.class, it);
}
-
+
@SuppressWarnings("unchecked")
private static T getAncestor(Class type, EObject it) {
- return it == null || type.isInstance(it)
- ? (T) it
- : getAncestor(type, it.eContainer());
+ return it == null || type.isInstance(it) ? (T) it : getAncestor(type, it.eContainer());
}
public static List getElementsWithExternalLabel(DNodeContainer dNodeContainer) {
@@ -128,14 +126,12 @@ public static List getElementsWithExternalLabel(DNodeContainer dNod
while (it.hasNext()) {
DDiagramElement dde = it.next();
Object bpmnElement = dde.getTarget();
- if ((bpmnElement instanceof Event)
- || (bpmnElement instanceof Gateway)
+ if ((bpmnElement instanceof Event) || (bpmnElement instanceof Gateway)
|| (bpmnElement instanceof ItemAwareElement)) {
if (!(bpmnElement instanceof BoundaryEvent) && isExternalLabel((DNode) dde)) {
result.add((BaseElement) bpmnElement);
}
- } else if ((bpmnElement instanceof Task)
- || (bpmnElement instanceof SubProcess)
+ } else if ((bpmnElement instanceof Task) || (bpmnElement instanceof SubProcess)
|| (bpmnElement instanceof CallActivity)) {
DNodeContainer dNodeTask = (DNodeContainer) dde;
for (DDiagramElement subDDE : dNodeTask.getElements()) {
@@ -152,18 +148,35 @@ public static List getElementsWithExternalLabel(DNodeContainer dNod
}
public static boolean isExternalLabel(DNode dNode) {
+ if (dNode != null && ServiceHelper.IS_EXTERNAL_LABEL.equals(dNode.getTooltipText())) {
+ //Crapy code used when the type of a Task or a Gateway is changed.
+ if (dNode.getStyle() != null || dNode.getOwnedStyle().getCustomFeatures() != null) {
+ setExternalLabel(dNode);
+ } else {
+ return true;
+ }
+ }
if (dNode == null || dNode.getOwnedStyle() == null || dNode.getOwnedStyle().getCustomFeatures() == null) {
return false;
}
return dNode.getOwnedStyle().getCustomFeatures().contains(ServiceHelper.IS_EXTERNAL_LABEL);
}
+ public static void setExternalLabelInTooltip(DNode dNode) {
+ //Crapy code used when the type of a Task or a Gateway is changed.
+ dNode.setTooltipText(IS_EXTERNAL_LABEL);
+ }
+
public static void setExternalLabel(DNode dNode) {
dNode.getStyle().getCustomFeatures().add(IS_EXTERNAL_LABEL);
+ //Crapy code used when the type of a Task or a Gateway is changed.
+ setExternalLabelInTooltip(dNode);
}
public static void setInternalLabel(DNode dNode) {
dNode.getStyle().getCustomFeatures().remove(IS_EXTERNAL_LABEL);
+ //Crapy code used when the type of a Task or a Gateway is changed.
+ dNode.setTooltipText("");
}
public static boolean isDefaultPath(DEdge dEdge) {
@@ -176,7 +189,7 @@ public static boolean isDefaultPath(DEdge dEdge) {
}
return result;
}
-
+
private static SequenceFlow getGatewayDefault(Gateway it) {
SequenceFlow result = null;
if (it instanceof InclusiveGateway) {
@@ -192,7 +205,7 @@ private static SequenceFlow getGatewayDefault(Gateway it) {
/**
* Moves a flow node from a container to another container.
*
- * @param element to mode
+ * @param element to mode
* @param oldSemanticContainer old container
* @param newSemanticContainer new container
*/
@@ -214,7 +227,7 @@ private List super FlowNode> getFlowNodeContainment(EObject container) {
// no empty list to indicate containment is not possible
return null;
}
-
+
public List getFlowNodeElements(EObject container, String className) {
Class> clazz = null;
try {
@@ -223,30 +236,22 @@ public List getFlowNodeElements(EObject container, String className) {
Activator.log(IStatus.ERROR, e.getMessage(), e);
return Collections.emptyList();
}
-
+
List> elements = getFlowNodeContainment(container);
- return elements == null
- ? Collections.emptyList()
- : elements.stream()
- .filter(clazz::isInstance)
- .map(FlowNode.class::cast)
- .collect(Collectors.toList());
+ return elements == null ? Collections.emptyList()
+ : elements.stream().filter(clazz::isInstance).map(FlowNode.class::cast).collect(Collectors.toList());
}
public List getDataInputs(EObject container) {
InputOutputSpecification ioSpec = getIoSpecification(container);
- return ioSpec != null
- ? ioSpec.getDataInputs()
- : Collections.emptyList();
+ return ioSpec != null ? ioSpec.getDataInputs() : Collections.emptyList();
}
public List getDataOutputs(EObject container) {
InputOutputSpecification ioSpec = getIoSpecification(container);
- return ioSpec != null
- ? ioSpec.getDataOutputs()
- : Collections.emptyList();
+ return ioSpec != null ? ioSpec.getDataOutputs() : Collections.emptyList();
}
-
+
private InputOutputSpecification getIoSpecification(EObject container) {
if (container instanceof Lane && ((Lane) container).getPartitionElement() instanceof InputOutputSpecification) {
return (InputOutputSpecification) ((Lane) container).getPartitionElement();
@@ -255,7 +260,7 @@ private InputOutputSpecification getIoSpecification(EObject container) {
}
return null;
}
-
+
/**
* Aborts a Sirius operation.
*
@@ -264,7 +269,7 @@ private InputOutputSpecification getIoSpecification(EObject container) {
*/
public static void abortOperation(EObject context) throws OperationCanceledException {
TransactionalEditingDomain edt = Session.of(context).get().getTransactionalEditingDomain();
- // Cancel Operation does not cancel !!
+ // Cancel Operation does not cancel !!
// ChangeContext catches them all !!
// What a trainer ...
((InternalTransactionalEditingDomain) edt).getActiveTransaction().abort(Status.CANCEL_STATUS);
diff --git a/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/TaskService.java b/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/TaskService.java
index 765de8fe..87330f3f 100644
--- a/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/TaskService.java
+++ b/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/TaskService.java
@@ -20,6 +20,7 @@
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.sirius.diagram.DDiagramElementContainer;
import org.eclipse.sirius.diagram.DNodeContainer;
+import org.obeonetwork.bpmn2.design.refactoring.SiriusElementRefactor;
import org.obeonetwork.dsl.bpmn2.Bpmn2Package;
import org.obeonetwork.dsl.bpmn2.BusinessRuleTask;
import org.obeonetwork.dsl.bpmn2.CallActivity;
diff --git a/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/refactoring/DiagramModifier.java b/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/refactoring/DiagramModifier.java
new file mode 100644
index 00000000..fca14e52
--- /dev/null
+++ b/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/refactoring/DiagramModifier.java
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2024 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *
+ */
+package org.obeonetwork.bpmn2.design.refactoring;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
+import org.eclipse.sirius.common.tools.api.util.RefreshIdsHolder;
+import org.eclipse.sirius.diagram.DSemanticDiagram;
+import org.eclipse.sirius.diagram.EdgeTarget;
+import org.eclipse.sirius.diagram.business.api.componentization.DiagramMappingsManager;
+import org.eclipse.sirius.diagram.business.api.componentization.DiagramMappingsManagerRegistry;
+import org.eclipse.sirius.diagram.business.internal.helper.decoration.DecorationHelperInternal;
+import org.eclipse.sirius.diagram.business.internal.sync.DDiagramElementSynchronizer;
+import org.eclipse.sirius.diagram.description.DiagramElementMapping;
+import org.eclipse.sirius.diagram.description.EdgeMapping;
+import org.eclipse.sirius.diagram.description.MappingBasedDecoration;
+import org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor;
+import org.eclipse.sirius.tools.api.SiriusPlugin;
+import org.eclipse.sirius.tools.api.interpreter.InterpreterUtil;
+import org.eclipse.sirius.viewpoint.description.SemanticBasedDecoration;
+
+/**
+ *
+ * @author nperansin
+ */
+@SuppressWarnings("restriction")
+class DiagramModifier {
+
+ final Session session;
+ final DSemanticDiagram parent;
+ final ModelAccessor accessor;
+ final IInterpreter interpreter;
+ final DDiagramElementSynchronizer dsync;
+ final DiagramMappingsManager mmapping;
+ final RefreshIdsHolder idFactory;
+
+ Map> mappingsToEdgeTargets = null;
+ final Map> edgeToMappings = new HashMap<>();
+ final Map> edgeToSemantics = new HashMap<>();
+
+ protected DiagramModifier(DSemanticDiagram diagram, Session session) {
+ this.session = session;
+ parent = diagram;
+ accessor = SiriusPlugin.getDefault().getModelAccessorRegistry().getModelAccessor(diagram);
+ mmapping = DiagramMappingsManagerRegistry.INSTANCE.getDiagramMappingsManager(session, diagram);
+ interpreter = InterpreterUtil.getInterpreter(diagram);
+ dsync = new DDiagramElementSynchronizer(diagram, interpreter, accessor);
+ idFactory = RefreshIdsHolder.getOrCreateHolder(diagram);
+ }
+
+ protected void prepareEdges() {
+ if (mappingsToEdgeTargets != null) {
+ return;
+ }
+ mappingsToEdgeTargets = dsync.computeMappingsToEdgeTargets(session.getSelectedViewpoints(false));
+ // Initialize cache
+ new DecorationHelperInternal(parent, interpreter, accessor).computeDecorations(mappingsToEdgeTargets,
+ edgeToSemantics, edgeToMappings);
+ // TODO update with new nodes ?
+ }
+
+}
diff --git a/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/refactoring/EdgeLayout.java b/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/refactoring/EdgeLayout.java
new file mode 100644
index 00000000..9f4fb073
--- /dev/null
+++ b/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/refactoring/EdgeLayout.java
@@ -0,0 +1,43 @@
+/**
+ * Copyright (c) 2024 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *
+ */
+package org.obeonetwork.bpmn2.design.refactoring;
+
+import org.eclipse.gmf.runtime.notation.Edge;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.sirius.diagram.DEdge;
+import org.eclipse.sirius.diagram.description.EdgeMapping;
+import org.eclipse.sirius.diagram.ui.business.api.view.SiriusGMFHelper;
+
+/**
+ *
+ * @author nperansin
+ */
+class EdgeLayout extends RepresentationLayout {
+
+ final EdgeLayoutData data;
+
+ protected EdgeLayout(DEdge src, Session session) {
+ super(src, src.getParentDiagram(), session);
+ View view = SiriusGMFHelper.getGmfView(src, session);
+ data = view instanceof Edge ? new EdgeLayoutData(src, (Edge) view) : null;
+ }
+
+ @Override
+ protected void update(DEdge target) {
+ View gmfView = SiriusGMFHelper.getGmfView(target, session);
+ if (gmfView instanceof Edge) {
+ data.update(target, (Edge) gmfView);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/refactoring/EdgeLayoutData.java b/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/refactoring/EdgeLayoutData.java
new file mode 100644
index 00000000..d04d6f4a
--- /dev/null
+++ b/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/refactoring/EdgeLayoutData.java
@@ -0,0 +1,107 @@
+/**
+ * Copyright (c) 2024 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *
+ */
+package org.obeonetwork.bpmn2.design.refactoring;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.gmf.runtime.notation.Anchor;
+import org.eclipse.gmf.runtime.notation.Bendpoints;
+import org.eclipse.gmf.runtime.notation.ConnectorStyle;
+import org.eclipse.gmf.runtime.notation.Edge;
+import org.eclipse.gmf.runtime.notation.FontStyle;
+import org.eclipse.gmf.runtime.notation.Node;
+import org.eclipse.sirius.diagram.DEdge;
+import org.eclipse.sirius.diagram.EdgeStyle;
+
+/**
+ *
+ * @author nperansin
+ */
+class EdgeLayoutData {
+
+ final Bendpoints bendPoints;
+ final Anchor sourceAnchor;
+ final Anchor targetAnchor;
+ final List labels;
+ final EdgeStyle oldSiriusStyle;
+ final EList> oldGMFStyles;
+
+ protected EdgeLayoutData(DEdge siriusSrc, Edge src) {
+ bendPoints = src.getBendpoints();
+ sourceAnchor = src.getSourceAnchor();
+ targetAnchor = src.getTargetAnchor();
+ this.oldSiriusStyle = (siriusSrc instanceof DEdge) ? (EdgeStyle) siriusSrc.getStyle() : null;
+ this.oldGMFStyles = src.getStyles();
+
+ labels = ((List>) src.getPersistedChildren()).stream()
+ .filter(it -> SiriusElementRefactorHelper.isGmfLabelNode(it)).map(Node.class::cast)
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * Updates edge with layout
+ *
+ * @param edge to update
+ */
+ protected void update(DEdge targetSiriusEdge, Edge edge) {
+ edge.setBendpoints(bendPoints);
+ edge.setSourceAnchor(sourceAnchor);
+ edge.setTargetAnchor(targetAnchor);
+ updateEdgeStyle(targetSiriusEdge, edge);
+ if (!labels.isEmpty()) {
+ updateLabels(edge);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void updateEdgeStyle(DEdge targetSiriusEdge, Edge targetEdge) {
+ if (oldSiriusStyle != null) {
+ SiriusElementRefactorHelper.updateSiriusEdgeStyle(oldSiriusStyle, (EdgeStyle) targetSiriusEdge.getStyle());
+ }
+
+ targetEdge.getStyles().forEach(newStyle -> {
+ Optional> oldStyleOpt = oldGMFStyles.stream()
+ .filter(oldStyle -> oldStyle.getClass().equals(newStyle.getClass())).findFirst();
+
+ oldStyleOpt.ifPresent(oldStyle -> {
+ if (oldStyle instanceof FontStyle && newStyle instanceof FontStyle) {
+ SiriusElementRefactorHelper.updateFontStyle((FontStyle) oldStyle, (FontStyle) newStyle);
+ } else if (oldStyle instanceof ConnectorStyle && newStyle instanceof ConnectorStyle) {
+ SiriusElementRefactorHelper.updateConnectorStyle((ConnectorStyle) oldStyle,
+ (ConnectorStyle) newStyle);
+ }
+ });
+ });
+ }
+
+ private void updateLabels(Edge edge) {
+ ((List>) edge.getPersistedChildren()).stream().filter(it -> SiriusElementRefactorHelper.isGmfLabelNode(it))
+ .map(Node.class::cast).forEach(it -> updateLabel(it));
+
+ }
+
+ private void updateLabel(Node it) {
+ Node old = findLabel(it.getType());
+ if (old != null) {
+ it.setLayoutConstraint(old.getLayoutConstraint());
+ }
+ }
+
+ private Node findLabel(String type) {
+ return labels.stream().filter(it -> Objects.equals(it.getType(), type)).findFirst().orElse(null);
+ }
+
+}
diff --git a/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/refactoring/EndLayout.java b/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/refactoring/EndLayout.java
new file mode 100644
index 00000000..aa548ed8
--- /dev/null
+++ b/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/refactoring/EndLayout.java
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2024 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *
+ */
+package org.obeonetwork.bpmn2.design.refactoring;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.sirius.diagram.AbstractDNode;
+import org.eclipse.sirius.diagram.DEdge;
+import org.eclipse.sirius.diagram.EdgeTarget;
+
+/**
+ *
+ * @author nperansin
+ */
+class EndLayout extends EdgeLayout {
+ final boolean targetChange;
+ final EdgeTarget end;
+ final boolean outEnd;
+ final boolean endChange;
+
+ protected EndLayout(DEdge src, AbstractDNode targeting, boolean out, Session session) {
+ super(src, session);
+ targetChange = src.getTarget() == targeting.getTarget();
+ outEnd = out;
+ end = SiriusElementRefactorHelper.getEnd(src, out);
+ endChange = end == targeting;
+ }
+
+ protected boolean match(DEdge it, AbstractDNode previous, AbstractDNode current) {
+ EObject expectedTarget = targetChange ? current.getTarget() : target.getTarget();
+ EdgeTarget actualEnd = SiriusElementRefactorHelper.getEnd(it, outEnd);
+ EdgeTarget expectedEnd = endChange ? (EdgeTarget) current : end;
+
+ return it.getTarget() == expectedTarget // proper target
+ && actualEnd == expectedEnd // proper end
+ && it.getMapping() == mapping; // proper mapping
+ }
+
+}
\ No newline at end of file
diff --git a/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/refactoring/NodeLayout.java b/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/refactoring/NodeLayout.java
new file mode 100644
index 00000000..24c1ff46
--- /dev/null
+++ b/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/refactoring/NodeLayout.java
@@ -0,0 +1,208 @@
+/**
+ * Copyright (c) 2024 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *
+ */
+package org.obeonetwork.bpmn2.design.refactoring;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.gmf.runtime.notation.Bounds;
+import org.eclipse.gmf.runtime.notation.FontStyle;
+import org.eclipse.gmf.runtime.notation.Location;
+import org.eclipse.gmf.runtime.notation.Node;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.sirius.diagram.AbstractDNode;
+import org.eclipse.sirius.diagram.DEdge;
+import org.eclipse.sirius.diagram.DNode;
+import org.eclipse.sirius.diagram.EdgeTarget;
+import org.eclipse.sirius.diagram.FlatContainerStyle;
+import org.eclipse.sirius.diagram.Square;
+import org.eclipse.sirius.diagram.WorkspaceImage;
+import org.eclipse.sirius.diagram.description.AbstractNodeMapping;
+import org.eclipse.sirius.diagram.ui.business.api.view.SiriusGMFHelper;
+import org.eclipse.sirius.viewpoint.Style;
+import org.obeonetwork.bpmn2.design.Activator;
+import org.obeonetwork.bpmn2.design.ServiceHelper;
+
+/**
+ *
+ * @author nperansin
+ */
+class NodeLayout extends RepresentationLayout {
+
+ private static final String LABEL_NODE_TYPE = "5003";
+
+ final Bounds bounds;
+ final Location labelLocation;
+ final List borders;
+ final List outEdges;
+ final List inEdges;
+ final boolean isExternalLabel;
+ final Style siriusStyle;
+ final EList> gmfStyles;
+
+ protected NodeLayout(AbstractDNode src, Session session) {
+ super(src, src.eContainer(), session);
+ this.isExternalLabel = src instanceof DNode ? ServiceHelper.isExternalLabel((DNode) src) : false;
+
+ Bounds bounds = null;
+ Location labelLocation = null;
+ EList> gmfStyles = null;
+ View gmfView = SiriusGMFHelper.getGmfView(src, session);
+ if (gmfView instanceof Node) {
+ Node node = (Node) gmfView;
+ if (node.getLayoutConstraint() instanceof Bounds) {
+ bounds = (Bounds) node.getLayoutConstraint();
+ for (Object o : node.getChildren()) {
+ if (o instanceof Node) {
+ Node subNode = (Node) o;
+ if (LABEL_NODE_TYPE.equals(subNode.getType())
+ && subNode.getLayoutConstraint() instanceof Location) {
+ labelLocation = (Location) subNode.getLayoutConstraint();
+ }
+ }
+ }
+ }
+ gmfStyles = node.getStyles();
+ }
+ this.bounds = bounds;
+ this.labelLocation = labelLocation;
+ this.gmfStyles = gmfStyles;
+ this.siriusStyle = src.getStyle();
+
+ borders = src.getOwnedBorderedNodes().stream().map(it -> new NodeLayout(it, session))
+ .collect(Collectors.toList());
+
+ if (src instanceof EdgeTarget) {
+ outEdges = ((EdgeTarget) src).getOutgoingEdges().stream().map(it -> new EndLayout(it, src, true, session))
+ .collect(Collectors.toList());
+ inEdges = ((EdgeTarget) src).getIncomingEdges().stream().map(it -> new EndLayout(it, src, false, session))
+ .collect(Collectors.toList());
+ } else {
+ outEdges = Collections.emptyList();
+ inEdges = Collections.emptyList();
+ }
+ }
+
+ @Override
+ protected void update(AbstractDNode target) {
+ // Update bounds
+ View gmfView = SiriusGMFHelper.getGmfView(target, session);
+ if (gmfView instanceof Node) {
+ Node node = (Node) gmfView;
+ node.setLayoutConstraint(bounds);
+ for (Object o : node.getChildren()) {
+ if (o instanceof Node) {
+ Node subNode = (Node) o;
+ if (LABEL_NODE_TYPE.equals(subNode.getType())) {
+ subNode.setLayoutConstraint(labelLocation);
+ }
+ }
+ }
+ }
+
+ updateNodeContainerStyle(target, gmfView instanceof Node ? (Node) gmfView : null);
+
+ if (target instanceof DNode && isExternalLabel) {
+ //Crapy code to set that the DNode has an external label.
+ ServiceHelper.setExternalLabelInTooltip((DNode) target);
+ }
+
+ // Update border
+ newView.getOwnedBorderedNodes().forEach(it -> updateBorder(it));
+
+ if (target instanceof EdgeTarget) {
+ ((EdgeTarget) target).getOutgoingEdges().stream().forEach(it -> updateEdge(it, outEdges, target));
+ ((EdgeTarget) target).getIncomingEdges().stream().forEach(it -> updateEdge(it, inEdges, target));
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void updateNodeContainerStyle(AbstractDNode target, Node gmfNode) {
+ if (target != null && (target.getStyle() instanceof FlatContainerStyle)
+ && (siriusStyle instanceof FlatContainerStyle)) {
+ SiriusElementRefactorHelper.updateSiriusNodeContainerFlatContainerStyle((FlatContainerStyle) siriusStyle,
+ (FlatContainerStyle) target.getStyle());
+ } else if (target != null && (target.getStyle() instanceof WorkspaceImage)
+ && (siriusStyle instanceof WorkspaceImage)) {
+ SiriusElementRefactorHelper.updateSiriusNodeContainerWorkspaceImageStyle((WorkspaceImage) siriusStyle,
+ (WorkspaceImage) target.getStyle());
+ } else if (target != null && (target.getStyle() instanceof Square) && (siriusStyle instanceof Square)) {
+ SiriusElementRefactorHelper.updateSiriusNodeContainerSquareStyle((Square) siriusStyle,
+ (Square) target.getStyle());
+ } else {
+ if (target == null || ((DNode) target).getStyle() == null) {
+ Activator.log(IStatus.ERROR, "Target or style is null: " + target.getStyle().getClass().getName() + "/"
+ + siriusStyle.getClass().getName(), null);
+ } else {
+ Activator.log(IStatus.ERROR, "Unknown types: " + target.getStyle().getClass().getName() + "/"
+ + siriusStyle.getClass().getName(), null);
+ }
+ }
+
+ if (gmfNode != null) {
+ gmfNode.getStyles().forEach(newStyle -> {
+ Optional> oldStyleOpt = gmfStyles.stream()
+ .filter(oldStyle -> oldStyle.getClass().equals(newStyle.getClass())).findFirst();
+
+ oldStyleOpt.ifPresent(oldStyle -> {
+ if (oldStyle instanceof FontStyle && newStyle instanceof FontStyle) {
+ SiriusElementRefactorHelper.updateFontStyle((FontStyle) oldStyle, (FontStyle) newStyle);
+ }
+ });
+ });
+ }
+ }
+
+ protected void updateEdge(DEdge current, List layouts, AbstractDNode newNode) {
+ EndLayout layout = findEdgeLayout(current, layouts, newNode);
+ if (layout != null) {
+ layout.update(current);
+ }
+ }
+
+ protected EndLayout findEdgeLayout(DEdge current, List layouts, AbstractDNode newNode) {
+ for (EndLayout layout : layouts) {
+ if (layout.match(current, target, newNode)) {
+ return layout;
+ }
+ }
+ return null;
+ }
+
+ protected void updateBorder(DNode border) {
+ NodeLayout layout = SiriusElementRefactorHelper.findLayout(borders, border);
+ if (layout != null) {
+ layout.updateBorderStyle(border);
+ }
+ }
+
+ protected void updateBorderStyle(AbstractDNode target) {
+ // Update bounds
+ View gmfView = SiriusGMFHelper.getGmfView(target, session);
+ if (gmfView instanceof Node) {
+ ((Node) gmfView).setLayoutConstraint(bounds);
+ }
+
+ updateNodeContainerStyle(target, gmfView instanceof Node ? (Node) gmfView : null);
+
+ if (target instanceof EdgeTarget) {
+ ((EdgeTarget) target).getOutgoingEdges().stream().forEach(it -> updateEdge(it, outEdges, target));
+ ((EdgeTarget) target).getIncomingEdges().stream().forEach(it -> updateEdge(it, inEdges, target));
+ }
+ }
+
+}
diff --git a/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/refactoring/RepresentationLayout.java b/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/refactoring/RepresentationLayout.java
new file mode 100644
index 00000000..2f872de8
--- /dev/null
+++ b/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/refactoring/RepresentationLayout.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2024 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *
+ */
+package org.obeonetwork.bpmn2.design.refactoring;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.sirius.diagram.DDiagramElement;
+import org.eclipse.sirius.diagram.description.DiagramElementMapping;
+
+/**
+ *
+ * @author nperansin
+ */
+abstract class RepresentationLayout {
+
+ final Session session;
+
+ final D target;
+ final EObject container; // DDiagram, AbstractDNode{border}, DNodeContainer, DNodeList
+ final M mapping;
+ D newView;
+
+ @SuppressWarnings("unchecked")
+ protected RepresentationLayout(D src, EObject parent, Session session) {
+
+ this.session = session;
+ target = src;
+ this.container = parent;
+ mapping = (M) src.getDiagramElementMapping();
+ }
+
+ protected void bind(D view) {
+ newView = view;
+ }
+
+ protected void update() {
+ if (newView != null) {
+ update(newView);
+ }
+ }
+
+ protected abstract void update(D newView);
+}
diff --git a/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/SiriusElementRefactor.java b/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/refactoring/SiriusElementRefactor.java
similarity index 50%
rename from plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/SiriusElementRefactor.java
rename to plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/refactoring/SiriusElementRefactor.java
index 68200172..90a6cfeb 100644
--- a/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/SiriusElementRefactor.java
+++ b/plugins/org.obeonetwork.dsl.bpmn2.design/src/org/obeonetwork/bpmn2/design/refactoring/SiriusElementRefactor.java
@@ -9,11 +9,9 @@
* Obeo - initial API and implementation
*
*/
-package org.obeonetwork.bpmn2.design;
+package org.obeonetwork.bpmn2.design.refactoring;
import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -23,6 +21,7 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
@@ -30,18 +29,10 @@
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.gmf.runtime.notation.Anchor;
-import org.eclipse.gmf.runtime.notation.Bendpoints;
-import org.eclipse.gmf.runtime.notation.Bounds;
import org.eclipse.gmf.runtime.notation.Diagram;
-import org.eclipse.gmf.runtime.notation.Edge;
-import org.eclipse.gmf.runtime.notation.Node;
-import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.sirius.business.api.dialect.DialectManager;
import org.eclipse.sirius.business.api.session.CustomDataConstants;
import org.eclipse.sirius.business.api.session.Session;
-import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
-import org.eclipse.sirius.common.tools.api.util.RefreshIdsHolder;
import org.eclipse.sirius.diagram.AbstractDNode;
import org.eclipse.sirius.diagram.DDiagram;
import org.eclipse.sirius.diagram.DDiagramElement;
@@ -52,33 +43,23 @@
import org.eclipse.sirius.diagram.DSemanticDiagram;
import org.eclipse.sirius.diagram.DragAndDropTarget;
import org.eclipse.sirius.diagram.EdgeTarget;
-import org.eclipse.sirius.diagram.business.api.componentization.DiagramMappingsManager;
-import org.eclipse.sirius.diagram.business.api.componentization.DiagramMappingsManagerRegistry;
-import org.eclipse.sirius.diagram.business.internal.helper.decoration.DecorationHelperInternal;
-import org.eclipse.sirius.diagram.business.internal.sync.DDiagramElementSynchronizer;
import org.eclipse.sirius.diagram.business.internal.sync.DEdgeCandidate;
import org.eclipse.sirius.diagram.business.internal.sync.DNodeCandidate;
import org.eclipse.sirius.diagram.description.AbstractNodeMapping;
import org.eclipse.sirius.diagram.description.ContainerMapping;
-import org.eclipse.sirius.diagram.description.DiagramElementMapping;
import org.eclipse.sirius.diagram.description.EdgeMapping;
import org.eclipse.sirius.diagram.description.IEdgeMapping;
-import org.eclipse.sirius.diagram.description.MappingBasedDecoration;
import org.eclipse.sirius.diagram.description.NodeMapping;
-import org.eclipse.sirius.diagram.ui.business.api.view.SiriusGMFHelper;
import org.eclipse.sirius.diagram.ui.internal.refresh.diagram.DDiagramCanonicalSynchronizer;
import org.eclipse.sirius.diagram.ui.part.SiriusDiagramEditor;
-import org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor;
-import org.eclipse.sirius.tools.api.SiriusPlugin;
-import org.eclipse.sirius.tools.api.interpreter.InterpreterUtil;
import org.eclipse.sirius.ui.business.api.session.SessionEditorInput;
import org.eclipse.sirius.viewpoint.DRepresentationDescriptor;
import org.eclipse.sirius.viewpoint.DRepresentationElement;
import org.eclipse.sirius.viewpoint.ViewpointPackage;
import org.eclipse.sirius.viewpoint.description.AnnotationEntry;
-import org.eclipse.sirius.viewpoint.description.SemanticBasedDecoration;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PlatformUI;
+import org.obeonetwork.bpmn2.design.Activator;
/**
* Refactor an element into a Sirius Session.
@@ -86,9 +67,11 @@
* This class is generic but only tested for nodes. (no case for edge in BPMN)
*
*
- * Simple approach (replacing a Representation target) does not work for diagrams.
+ * Simple approach (replacing a Representation target) does not work for
+ * diagrams.
*
- *
Editor contains a map from Semantic element to Representation that is not refreshed on simple change.
+ *
Editor contains a map from Semantic element to Representation that is not
+ * refreshed on simple change.
*
Unedited diagrams may be impacted and positions are lost.