From f31bd42e4402dd623b6f8ca33c5e96c037f0084d Mon Sep 17 00:00:00 2001 From: prmr Date: Tue, 23 Feb 2021 14:02:10 -0500 Subject: [PATCH] #416 Refactor constraint about edge end in sequence diagram The case where trying to create a constructor edge was implemented as a special case in constraints, where the constraint was only added to the constraint set if the call could be a legal constructor call. This divergence from the design, where all constraints are stored in a set, was creating an obstacle to the future improvement of the constraint management. With this change, all constraints are implemented as predicates. --- .../diagram/builder/SequenceDiagramBuilder.java | 8 ++------ .../SequenceDiagramEdgeConstraints.java | 14 +++++++++++--- .../TestSequenceDiagramEdgeConstraints.java | 8 ++++---- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/ca/mcgill/cs/jetuml/diagram/builder/SequenceDiagramBuilder.java b/src/ca/mcgill/cs/jetuml/diagram/builder/SequenceDiagramBuilder.java index 7c156f543..421cc2059 100644 --- a/src/ca/mcgill/cs/jetuml/diagram/builder/SequenceDiagramBuilder.java +++ b/src/ca/mcgill/cs/jetuml/diagram/builder/SequenceDiagramBuilder.java @@ -72,13 +72,9 @@ protected ConstraintSet getAdditionalEdgeConstraints(Edge pEdge, Node pStart, No EdgeConstraints.maxEdges(pEdge, pStart, pEnd, aDiagram, 1), SequenceDiagramEdgeConstraints.noEdgesFromParameterTop(pStart, pStartPoint), SequenceDiagramEdgeConstraints.returnEdge(pEdge, pStart, pEnd, aDiagram), - SequenceDiagramEdgeConstraints.singleEntryPoint(pEdge, pStart, aDiagram) + SequenceDiagramEdgeConstraints.singleEntryPoint(pEdge, pStart, aDiagram), + SequenceDiagramEdgeConstraints.callEdgeEnd(pEdge, pStart, pEnd, pEndPoint, aDiagram) ); - if( !canCreateConstructorCall(pStartPoint, pEndPoint) ) - { - // The edge could not land on the top rectangle of ImplicitParameterNode if cannot create constructor call - constraintSet.merge( new ConstraintSet(SequenceDiagramEdgeConstraints.callEdgeEnd(pEdge, pEnd, pEndPoint)) ); - } return constraintSet; } diff --git a/src/ca/mcgill/cs/jetuml/diagram/builder/constraints/SequenceDiagramEdgeConstraints.java b/src/ca/mcgill/cs/jetuml/diagram/builder/constraints/SequenceDiagramEdgeConstraints.java index c6b656bd9..31810de3b 100644 --- a/src/ca/mcgill/cs/jetuml/diagram/builder/constraints/SequenceDiagramEdgeConstraints.java +++ b/src/ca/mcgill/cs/jetuml/diagram/builder/constraints/SequenceDiagramEdgeConstraints.java @@ -73,18 +73,26 @@ public static Constraint returnEdge(Edge pEdge, Node pStart, Node pEnd, Diagram } /* - * Call edges that land on a parameter node must land on the lifeline part. + * Call edges that land on a parameter node must land on the lifeline part, + * except if it is allowed to create a constructor. */ - public static Constraint callEdgeEnd(Edge pEdge, Node pEndNode, Point pEndPoint) + public static Constraint callEdgeEnd(Edge pEdge, Node pStartNode, Node pEndNode, Point pEndPoint, Diagram pDiagram) { return ()-> { return !(pEdge.getClass() == CallEdge.class && pEndNode.getClass() == ImplicitParameterNode.class && - IMPLICIT_PARAMETER_NODE_VIEWER.getTopRectangle(pEndNode).contains(pEndPoint)); + IMPLICIT_PARAMETER_NODE_VIEWER.getTopRectangle(pEndNode).contains(pEndPoint) && + !canCreateConstructor(pStartNode, pEndNode, pDiagram, pEndPoint)); }; } + private static boolean canCreateConstructor(Node pStartNode, Node pEndNode, Diagram pDiagram, Point pEndPoint) + { + return (pStartNode instanceof ImplicitParameterNode || pStartNode instanceof CallNode) && + new ControlFlow(pDiagram).canCreateConstructedObject(pEndNode, pEndPoint); + } + /* * It's only legal to start an interaction on a parameter node if there are no existing activations * in the diagram. diff --git a/test/ca/mcgill/cs/jetuml/diagram/builder/constraints/TestSequenceDiagramEdgeConstraints.java b/test/ca/mcgill/cs/jetuml/diagram/builder/constraints/TestSequenceDiagramEdgeConstraints.java index 288332d42..1e2fb7e76 100644 --- a/test/ca/mcgill/cs/jetuml/diagram/builder/constraints/TestSequenceDiagramEdgeConstraints.java +++ b/test/ca/mcgill/cs/jetuml/diagram/builder/constraints/TestSequenceDiagramEdgeConstraints.java @@ -156,28 +156,28 @@ public void testreturnEdgeValid() public void testCallEdgeEndNotCallEdge() { createDiagram(); - assertTrue(SequenceDiagramEdgeConstraints.callEdgeEnd(aReturnEdge, aCallNode2, new Point(10,10)).satisfied()); + assertTrue(SequenceDiagramEdgeConstraints.callEdgeEnd(aReturnEdge, aCallNode2, aCallNode1, new Point(10,10), aDiagram).satisfied()); } @Test public void testCallEdgeEndEndNotParameter() { createDiagram(); - assertTrue(SequenceDiagramEdgeConstraints.callEdgeEnd(aCallEdge, aCallNode2, new Point(10,10)).satisfied()); + assertTrue(SequenceDiagramEdgeConstraints.callEdgeEnd(aCallEdge, aCallNode2, aCallNode1, new Point(10,10), aDiagram).satisfied()); } @Test public void testCallEdgeEndEndOnLifeLine() { createDiagram(); - assertTrue(SequenceDiagramEdgeConstraints.callEdgeEnd(aCallEdge, aParameter2, new Point(0,85)).satisfied()); + assertTrue(SequenceDiagramEdgeConstraints.callEdgeEnd(aCallEdge, aParameter2, aCallNode1, new Point(0,85), aDiagram).satisfied()); } @Test public void testCallEdgeEndEndOnTopRectangle() { createDiagram(); - assertFalse(SequenceDiagramEdgeConstraints.callEdgeEnd(aCallEdge, aParameter2, new Point(0,5)).satisfied()); + assertTrue(SequenceDiagramEdgeConstraints.callEdgeEnd(aCallEdge, aParameter2, aCallNode1, new Point(0,5), aDiagram).satisfied()); } @Test