1+
12/********************************************************************************
23 * Copyright (c) 2022 Imixs Software Solutions GmbH and others.
34 *
2122
2223import org .eclipse .emf .common .command .Command ;
2324import org .eclipse .emf .common .util .EList ;
25+ import org .eclipse .glsp .graph .GBoundsAware ;
2426import org .eclipse .glsp .graph .GEdge ;
27+ import org .eclipse .glsp .graph .GModelElement ;
2528import org .eclipse .glsp .graph .GPoint ;
29+ import org .eclipse .glsp .graph .util .GraphUtil ;
2630import org .eclipse .glsp .server .operations .ChangeRoutingPointsOperation ;
2731import org .eclipse .glsp .server .operations .GModelOperationHandler ;
2832import org .eclipse .glsp .server .types .ElementAndRoutingPoints ;
33+ import org .openbpmn .bpmn .BPMNModel ;
2934import org .openbpmn .bpmn .BPMNTypes ;
3035import org .openbpmn .bpmn .elements .Association ;
3136import org .openbpmn .bpmn .elements .BPMNProcess ;
37+ import org .openbpmn .bpmn .elements .Event ;
3238import org .openbpmn .bpmn .elements .Participant ;
3339import org .openbpmn .bpmn .elements .SequenceFlow ;
3440import org .openbpmn .bpmn .elements .core .BPMNElement ;
3541import org .openbpmn .bpmn .elements .core .BPMNElementEdge ;
42+ import org .openbpmn .bpmn .elements .core .BPMNElementNode ;
3643import org .openbpmn .bpmn .elements .core .BPMNPoint ;
44+ import org .openbpmn .bpmn .exceptions .BPMNMissingElementException ;
3745import org .openbpmn .glsp .model .BPMNGModelState ;
3846import org .openbpmn .glsp .utils .BPMNGridSnapper ;
3947
@@ -85,19 +93,27 @@ private void executeOperation(final ChangeRoutingPointsOperation operation) {
8593
8694 EList <GPoint > oldPoints = edge .getRoutingPoints ();
8795 if (debug )
88- System .out .println ("│ ├── old points:" );
96+ System .out .println ("│ ├── old points:" );
8997 for (GPoint ding : oldPoints ) {
9098 if (debug )
91- System .out .println ("│ │ ├── " + ding .getX () + "." + ding .getY ());
99+ System .out .println ("│ │ ├── " + ding .getX () + "." + ding .getY ());
92100 }
93101 if (debug )
94- System .out .println ("│ ├── new points:" );
102+ System .out .println ("│ ├── new points:" );
95103 for (GPoint ding : newGLSPRoutingPoints ) {
96104 if (debug )
97- System .out .println ("│ │ ├── " + ding .getX () + "." + ding .getY ());
105+ System .out .println ("│ │ ├── " + ding .getX () + "." + ding .getY ());
106+ }
107+
108+ // Adjust routing points for Events
109+ if (!newGLSPRoutingPoints .isEmpty ()) {
110+ adjustEventRoutingPorts (edge , newGLSPRoutingPoints );
98111 }
112+
113+ // Update BPMN Routing
99114 edge .getRoutingPoints ().clear ();
100115 edge .getRoutingPoints ().addAll (newGLSPRoutingPoints );
116+
101117 updateBPMNWayPoints (id , newGLSPRoutingPoints );
102118 }
103119 }
@@ -107,6 +123,108 @@ private void executeOperation(final ChangeRoutingPointsOperation operation) {
107123 // no more action - the GModel is now up to date
108124 }
109125
126+ /**
127+ * This helper method adjusts the docking point of the last/first routing point
128+ * on a BPMN Event element.
129+ *
130+ * @throws BPMNMissingElementException
131+ *
132+ */
133+ private void adjustEventRoutingPorts (GEdge edge , List <GPoint > newGLSPRoutingPoints )
134+ throws BPMNMissingElementException {
135+
136+ GPoint pointOfInterest = null ;
137+ // ist die Source ein Event?
138+ BPMNElementNode sourceBPMNElement = modelState .getBpmnModel ().findElementNodeById (edge .getSourceId ());
139+ if (sourceBPMNElement != null && BPMNModel .isEvent (sourceBPMNElement )) {
140+ pointOfInterest = newGLSPRoutingPoints .get (0 );
141+ GPoint center = computeCenter (edge .getSource ());
142+ if (yInEventsBounds (center , pointOfInterest )) {
143+ pointOfInterest .setY (center .getY ());
144+ }
145+ if (xInEventsBounds (center , pointOfInterest )) {
146+ pointOfInterest .setX (center .getX ());
147+ }
148+ }
149+
150+ // ist das Target ein Event?
151+ BPMNElementNode targetBPMNElement = modelState .getBpmnModel ().findElementNodeById (edge .getTargetId ());
152+ if (targetBPMNElement != null && BPMNModel .isEvent (targetBPMNElement )) {
153+ pointOfInterest = newGLSPRoutingPoints .get (newGLSPRoutingPoints .size () - 1 );
154+ GPoint center = computeCenter (edge .getTarget ());
155+ if (yInEventsBounds (center , pointOfInterest )) {
156+ pointOfInterest .setY (center .getY ());
157+ }
158+ if (xInEventsBounds (center , pointOfInterest )) {
159+ pointOfInterest .setX (center .getX ());
160+ }
161+ }
162+ }
163+
164+ /**
165+ * Returns the center of a GMoelElement
166+ *
167+ * @param element
168+ * @return
169+ */
170+ private GPoint computeCenter (GModelElement element ) {
171+ if (element instanceof GBoundsAware ) {
172+ GBoundsAware boundsElement = (GBoundsAware ) element ;
173+ double radius = Event .DEFAULT_HEIGHT / 2 ;
174+ double xCenter = boundsElement .getPosition ().getX () + radius ;
175+ double yCenter = boundsElement .getPosition ().getY () + radius ;
176+ return GraphUtil .point (xCenter , yCenter );
177+ }
178+ return GraphUtil .point (0 , 0 );
179+
180+ }
181+
182+ private boolean yInEventsBounds (GPoint center , GPoint routingPoint ) throws BPMNMissingElementException {
183+ double radius = Event .DEFAULT_HEIGHT / 2 ;
184+
185+ // Get first routing point and test position....
186+ if (debug ) {
187+ System .out .println ("│ ├── event center = " + center );
188+ System .out .println ("│ ├── 1st routing point = " + routingPoint );
189+ }
190+ // test y
191+ double rY = routingPoint .getY ();
192+ if (debug ) {
193+ System .out .println ("│ ├── eY - radius = " + (center .getY () - radius ));
194+ System .out .println ("│ ├── eY + radius = " + (center .getY () + radius ));
195+ }
196+ if (rY >= (center .getY () - radius )
197+ && rY <= (center .getY () + radius )) {
198+ if (debug )
199+ System .out .println ("│ ├── Adjusting necessary" );
200+ return true ;
201+ }
202+ return false ;
203+ }
204+
205+ private boolean xInEventsBounds (GPoint center , GPoint routingPoint ) throws BPMNMissingElementException {
206+ double radius = Event .DEFAULT_HEIGHT / 2 ;
207+
208+ // Get first routing point and test position....
209+ if (debug ) {
210+ System .out .println ("│ ├── event center = " + center );
211+ System .out .println ("│ ├── 1st routing point = " + routingPoint );
212+ }
213+ // test y
214+ double rX = routingPoint .getX ();
215+ if (debug ) {
216+ System .out .println ("│ ├── eX - radius = " + (center .getX () - radius ));
217+ System .out .println ("│ ├── eX + radius = " + (center .getX () + radius ));
218+ }
219+ if (rX >= (center .getX () - radius )
220+ && rX <= (center .getX () + radius )) {
221+ if (debug )
222+ System .out .println ("│ ├── Adjusting necessary" );
223+ return true ;
224+ }
225+ return false ;
226+ }
227+
110228 /**
111229 * This helper method is necessary to update parts of the BPMN waypoints
112230 * immediately.
@@ -125,7 +243,7 @@ private void updateBPMNWayPoints(String id, List<GPoint> newGLSPRoutingPoints) {
125243
126244 try {
127245 if (debug )
128- System .out .println ("│ ├── clearing all waypoints" );
246+ System .out .println ("│ ├── clearing all waypoints" );
129247 bpmnElementEdge .clearWayPoints ();
130248
131249 // find the process
@@ -156,12 +274,12 @@ private void updateBPMNWayPoints(String id, List<GPoint> newGLSPRoutingPoints) {
156274 }
157275 bpmnPoint = new BPMNPoint (xOffset + point .getX (), yOffset + point .getY ());
158276 if (debug )
159- System .out .println ("│ ├── add waypoint : " + point .getX () + "," + point .getY ());
277+ System .out .println ("│ ├── add waypoint : " + point .getX () + "," + point .getY ());
160278 bpmnElementEdge .addWayPoint (bpmnPoint );
161279 }
162280 } catch (Exception e ) {
163- logger .info ("Unable to update bpmn way points: " + e .getMessage ());
281+ logger .warning ("Unable to update bpmn way points: " + e .getMessage ());
164282 e .printStackTrace ();
165283 }
166284 }
167- }
285+ }
0 commit comments