Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/DefaultConnectionRouter.java')
-rw-r--r--plugins/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/DefaultConnectionRouter.java294
1 files changed, 276 insertions, 18 deletions
diff --git a/plugins/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/DefaultConnectionRouter.java b/plugins/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/DefaultConnectionRouter.java
index d8fc1da1..51ac9ac8 100644
--- a/plugins/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/DefaultConnectionRouter.java
+++ b/plugins/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/DefaultConnectionRouter.java
@@ -18,14 +18,22 @@ import java.util.Comparator;
import java.util.List;
import org.eclipse.bpmn2.BaseElement;
+import org.eclipse.bpmn2.BoundaryEvent;
import org.eclipse.bpmn2.FlowElementsContainer;
import org.eclipse.bpmn2.Lane;
import org.eclipse.bpmn2.di.BPMNShape;
+import org.eclipse.bpmn2.modeler.core.utils.AnchorSite;
+import org.eclipse.bpmn2.modeler.core.utils.AnchorType;
+import org.eclipse.bpmn2.modeler.core.utils.AnchorUtil;
+import org.eclipse.bpmn2.modeler.core.utils.BoundaryEventPositionHelper;
+import org.eclipse.bpmn2.modeler.core.utils.BoundaryEventPositionHelper.PositionOnLine;
import org.eclipse.bpmn2.modeler.core.utils.BusinessObjectUtil;
import org.eclipse.bpmn2.modeler.core.utils.FeatureSupport;
import org.eclipse.bpmn2.modeler.core.utils.GraphicsUtil;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.graphiti.datatypes.IDimension;
+import org.eclipse.graphiti.datatypes.ILocation;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.context.IAddConnectionContext;
import org.eclipse.graphiti.features.context.IAddContext;
@@ -36,6 +44,7 @@ import org.eclipse.graphiti.mm.algorithms.Polyline;
import org.eclipse.graphiti.mm.algorithms.styles.LineStyle;
import org.eclipse.graphiti.mm.algorithms.styles.Point;
import org.eclipse.graphiti.mm.pictograms.Anchor;
+import org.eclipse.graphiti.mm.pictograms.AnchorContainer;
import org.eclipse.graphiti.mm.pictograms.Connection;
import org.eclipse.graphiti.mm.pictograms.ConnectionDecorator;
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
@@ -69,6 +78,10 @@ public class DefaultConnectionRouter extends AbstractConnectionRouter {
/** The target anchor. */
protected FixPointAnchor sourceAnchor, targetAnchor;
+
+ AnchorSite sourceAnchorSites[];
+
+ AnchorSite targetAnchorSites[];
/**
* Instantiates a new default connection router.
@@ -87,16 +100,31 @@ public class DefaultConnectionRouter extends AbstractConnectionRouter {
this.connection = connection;
this.sourceAnchor = (FixPointAnchor) connection.getStart();
this.targetAnchor = (FixPointAnchor) connection.getEnd();
- this.source = (Shape) sourceAnchor.getParent();
- this.target = (Shape) targetAnchor.getParent();
+ this.source = (Shape) AnchorUtil.getAnchorContainer(sourceAnchor);
+ this.target = (Shape) AnchorUtil.getAnchorContainer(targetAnchor);
return false;
}
/* (non-Javadoc)
+ * @see org.eclipse.bpmn2.modeler.core.features.IConnectionRouter#canRoute(org.eclipse.graphiti.mm.pictograms.Connection)
+ */
+ @Override
+ public boolean canRoute(Connection connection) {
+ // don't touch Choreography Task Message Links.
+ AnchorContainer ac = AnchorUtil.getAnchorContainer(connection.getStart());
+ if (AnchorType.getType(ac) == AnchorType.MESSAGELINK)
+ return false;
+ ac = AnchorUtil.getAnchorContainer(connection.getEnd());
+ if (AnchorType.getType(ac) == AnchorType.MESSAGELINK)
+ return false;
+ return true;
+ }
+
+ /* (non-Javadoc)
* @see org.eclipse.bpmn2.modeler.core.features.IConnectionRouter#needsUpdate(org.eclipse.graphiti.mm.pictograms.Connection)
*/
@Override
- public boolean needsLayout(Connection connection) {
+ public boolean routingNeeded(Connection connection) {
return false;
}
@@ -246,38 +274,45 @@ public class DefaultConnectionRouter extends AbstractConnectionRouter {
}
/**
- * Find crossings.
+ * Find Connection line crossings. This will return a list of all
+ * Connections on the Diagram that intersect any line segment of the given
+ * Connection. Connections that are attached to the given Connection are
+ * ignored.
*
- * @param start the start
- * @param end the end
- * @return the list
+ * @param connection the Connection to test.
+ * @param start the starting point of a line segment on the connection.
+ * @param end the ending point of the line segment.
+ * @return a list of Connections that cross over the line segment.
*/
- protected List<Connection> findCrossings(Point start, Point end) {
+ protected List<Connection> findCrossings(Connection connection, Point start, Point end) {
// TODO: figure out why this isn't working!
List<Connection> crossings = new ArrayList<Connection>();
List<Connection> allConnections = fp.getDiagramTypeProvider().getDiagram().getConnections();
- for (Connection connection : allConnections) {
- if (Graphiti.getPeService().getProperty(connection, RoutingNet.CONNECTION)!=null) {
+ List<FixPointAnchor> connectionAnchors = AnchorUtil.getAnchors(connection);
+ for (Connection c : allConnections) {
+ if (Graphiti.getPeService().getProperty(c, RoutingNet.CONNECTION)!=null) {
continue;
}
- Point p1 = GraphicsUtil.createPoint(connection.getStart());
- Point p3 = GraphicsUtil.createPoint(connection.getEnd());
- if (connection instanceof FreeFormConnection) {
- FreeFormConnection ffc = (FreeFormConnection) connection;
+ if (connectionAnchors.contains(c.getStart()) || connectionAnchors.contains(c.getEnd()))
+ continue;
+ Point p1 = GraphicsUtil.createPoint(c.getStart());
+ Point p3 = GraphicsUtil.createPoint(c.getEnd());
+ if (c instanceof FreeFormConnection) {
+ FreeFormConnection ffc = (FreeFormConnection) c;
Point p2 = p1;
for (Point p : ffc.getBendpoints()) {
if (GraphicsUtil.intersects(start, end, p1, p)) {
- crossings.add(connection);
+ crossings.add(c);
break;
}
p2 = p1 = p;
}
if (GraphicsUtil.intersects(start, end, p2, p3)) {
- crossings.add(connection);
+ crossings.add(c);
}
}
else if (GraphicsUtil.intersects(start, end, p1, p3)) {
- crossings.add(connection);
+ crossings.add(c);
}
}
return crossings;
@@ -321,6 +356,229 @@ public class DefaultConnectionRouter extends AbstractConnectionRouter {
}
}
+ protected void calculateAllowedAnchorSites() {
+
+ EObject bo = BusinessObjectUtil.getBusinessObjectForPictogramElement(source);
+ if (bo instanceof BoundaryEvent) {
+ sourceAnchorSites = calculateBoundaryEventAnchorSites(source);
+ }
+ bo = BusinessObjectUtil.getBusinessObjectForPictogramElement(target);
+ if (bo instanceof BoundaryEvent) {
+ targetAnchorSites = calculateBoundaryEventAnchorSites(target);
+ }
+ if (AnchorType.getType(source) == AnchorType.CONNECTION) {
+ sourceAnchorSites = new AnchorSite[1];
+ sourceAnchorSites[0] = AnchorSite.CENTER;
+ }
+ if (AnchorType.getType(target) == AnchorType.CONNECTION) {
+ targetAnchorSites = new AnchorSite[1];
+ targetAnchorSites[0] = AnchorSite.CENTER;
+ }
+ ILocation sPos = Graphiti.getPeService().getLocationRelativeToDiagram(source);
+ IDimension sSize = GraphicsUtil.calculateSize(source);
+ ILocation tPos = Graphiti.getPeService().getLocationRelativeToDiagram(target);
+ IDimension tSize = GraphicsUtil.calculateSize(target);
+ // find relative locations
+ if (sPos.getX()+sSize.getWidth() < tPos.getX()) {
+ // source shape is to left of target
+ if (sPos.getY()+sSize.getHeight() < tPos.getY()) {
+ // source shape is to left and above target:
+ // omit the two opposite sides of both source and target
+ if (sourceAnchorSites==null) {
+ sourceAnchorSites = new AnchorSite[2];
+ sourceAnchorSites[0] = AnchorSite.RIGHT;
+ sourceAnchorSites[1] = AnchorSite.BOTTOM;
+ }
+ if (targetAnchorSites==null) {
+ targetAnchorSites = new AnchorSite[2];
+ targetAnchorSites[0] = AnchorSite.LEFT;
+ targetAnchorSites[1] = AnchorSite.TOP;
+ }
+ }
+ else if(sPos.getY() > tPos.getY()+tSize.getHeight()) {
+ // source shape is to left and below target
+ if (sourceAnchorSites==null) {
+ sourceAnchorSites = new AnchorSite[2];
+ sourceAnchorSites[0] = AnchorSite.RIGHT;
+ sourceAnchorSites[1] = AnchorSite.TOP;
+ }
+ if (targetAnchorSites==null) {
+ targetAnchorSites = new AnchorSite[2];
+ targetAnchorSites[0] = AnchorSite.LEFT;
+ targetAnchorSites[1] = AnchorSite.BOTTOM;
+ }
+ }
+ else {
+ if (sourceAnchorSites==null) {
+ sourceAnchorSites = new AnchorSite[3];
+ sourceAnchorSites[0] = AnchorSite.RIGHT;
+ sourceAnchorSites[1] = AnchorSite.TOP;
+ sourceAnchorSites[2] = AnchorSite.BOTTOM;
+ }
+ if (targetAnchorSites==null) {
+ targetAnchorSites = new AnchorSite[3];
+ targetAnchorSites[0] = AnchorSite.LEFT;
+ targetAnchorSites[1] = AnchorSite.TOP;
+ targetAnchorSites[2] = AnchorSite.BOTTOM;
+ }
+ }
+ }
+ else if (sPos.getX() > tPos.getX()+tSize.getWidth()) {
+ // source shape is to right of target
+ if (sPos.getY()+sSize.getHeight() < tPos.getY()) {
+ // source shape is to right and above target
+ if (sourceAnchorSites==null) {
+ sourceAnchorSites = new AnchorSite[2];
+ sourceAnchorSites[0] = AnchorSite.LEFT;
+ sourceAnchorSites[1] = AnchorSite.BOTTOM;
+ }
+ if (targetAnchorSites==null) {
+ targetAnchorSites = new AnchorSite[2];
+ targetAnchorSites[0] = AnchorSite.RIGHT;
+ targetAnchorSites[1] = AnchorSite.TOP;
+ }
+ }
+ else if(sPos.getY() > tPos.getY()+tSize.getHeight()) {
+ // source shape is to right and below target
+ if (sourceAnchorSites==null) {
+ sourceAnchorSites = new AnchorSite[2];
+ sourceAnchorSites[0] = AnchorSite.LEFT;
+ sourceAnchorSites[1] = AnchorSite.TOP;
+ }
+ if (targetAnchorSites==null) {
+ targetAnchorSites = new AnchorSite[2];
+ targetAnchorSites[0] = AnchorSite.RIGHT;
+ targetAnchorSites[1] = AnchorSite.BOTTOM;
+ }
+ }
+ else {
+ if (sourceAnchorSites==null) {
+ sourceAnchorSites = new AnchorSite[3];
+ sourceAnchorSites[0] = AnchorSite.LEFT;
+ sourceAnchorSites[1] = AnchorSite.TOP;
+ sourceAnchorSites[2] = AnchorSite.BOTTOM;
+ }
+ if (targetAnchorSites==null) {
+ targetAnchorSites = new AnchorSite[3];
+ targetAnchorSites[0] = AnchorSite.RIGHT;
+ targetAnchorSites[1] = AnchorSite.TOP;
+ targetAnchorSites[2] = AnchorSite.BOTTOM;
+ }
+ }
+ }
+ else if (sPos.getY()+sSize.getHeight() < tPos.getY()) {
+ // source shape is above target
+ if (sourceAnchorSites==null) {
+ sourceAnchorSites = new AnchorSite[3];
+ sourceAnchorSites[0] = AnchorSite.LEFT;
+ sourceAnchorSites[1] = AnchorSite.RIGHT;
+ sourceAnchorSites[2] = AnchorSite.BOTTOM;
+ }
+ if (targetAnchorSites==null) {
+ targetAnchorSites = new AnchorSite[3];
+ targetAnchorSites[0] = AnchorSite.LEFT;
+ targetAnchorSites[1] = AnchorSite.RIGHT;
+ targetAnchorSites[2] = AnchorSite.TOP;
+ }
+ }
+ else if(sPos.getY() > tPos.getY()+tSize.getHeight()) {
+ // source shape is below target
+ if (sourceAnchorSites==null) {
+ sourceAnchorSites = new AnchorSite[3];
+ sourceAnchorSites[0] = AnchorSite.LEFT;
+ sourceAnchorSites[1] = AnchorSite.RIGHT;
+ sourceAnchorSites[2] = AnchorSite.TOP;
+ }
+ if (targetAnchorSites==null) {
+ targetAnchorSites = new AnchorSite[3];
+ targetAnchorSites[0] = AnchorSite.LEFT;
+ targetAnchorSites[1] = AnchorSite.RIGHT;
+ targetAnchorSites[2] = AnchorSite.BOTTOM;
+ }
+ }
+ else {
+ // source and target overlap
+ if (sourceAnchorSites==null) {
+ sourceAnchorSites = new AnchorSite[4];
+ sourceAnchorSites[0] = AnchorSite.LEFT;
+ sourceAnchorSites[1] = AnchorSite.RIGHT;
+ sourceAnchorSites[2] = AnchorSite.TOP;
+ sourceAnchorSites[3] = AnchorSite.BOTTOM;
+ }
+ if (targetAnchorSites==null) {
+ targetAnchorSites = new AnchorSite[4];
+ targetAnchorSites[0] = AnchorSite.LEFT;
+ targetAnchorSites[1] = AnchorSite.RIGHT;
+ targetAnchorSites[2] = AnchorSite.TOP;
+ targetAnchorSites[3] = AnchorSite.BOTTOM;
+ }
+ }
+ }
+
+ protected AnchorSite[] calculateBoundaryEventAnchorSites(Shape shape) {
+ AnchorSite sites[];
+ PositionOnLine pol = BoundaryEventPositionHelper.getPositionOnLineProperty(shape);
+ switch (pol.getLocationType()) {
+ case BOTTOM:
+ sites = new AnchorSite[1];
+ sites[0] = AnchorSite.BOTTOM;
+ break;
+ case BOTTOM_LEFT:
+ sites = new AnchorSite[2];
+ sites[0] = AnchorSite.BOTTOM;
+ sites[1] = AnchorSite.LEFT;
+ break;
+ case BOTTOM_RIGHT:
+ sites = new AnchorSite[2];
+ sites[0] = AnchorSite.BOTTOM;
+ sites[1] = AnchorSite.RIGHT;
+ break;
+ case LEFT:
+ sites = new AnchorSite[1];
+ sites[0] = AnchorSite.LEFT;
+ break;
+ case RIGHT:
+ sites = new AnchorSite[1];
+ sites[0] = AnchorSite.RIGHT;
+ break;
+ case TOP:
+ sites = new AnchorSite[1];
+ sites[0] = AnchorSite.TOP;
+ break;
+ case TOP_LEFT:
+ sites = new AnchorSite[2];
+ sites[0] = AnchorSite.TOP;
+ sites[1] = AnchorSite.LEFT;
+ break;
+ case TOP_RIGHT:
+ sites = new AnchorSite[2];
+ sites[0] = AnchorSite.TOP;
+ sites[1] = AnchorSite.RIGHT;
+ break;
+ default:
+ sites = new AnchorSite[4];
+ sites[0] = AnchorSite.TOP;
+ sites[1] = AnchorSite.LEFT;
+ sites[2] = AnchorSite.BOTTOM;
+ sites[3] = AnchorSite.RIGHT;
+ break;
+ }
+ return sites;
+ }
+
+ protected boolean shouldCalculate(AnchorSite sourceSite, AnchorSite targetSite) {
+ for (int i=0; i<sourceAnchorSites.length; ++i) {
+ if (sourceSite == sourceAnchorSites[i]) {
+ for (int j=0; j<targetAnchorSites.length; ++j) {
+ if (targetSite == targetAnchorSites[j]) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
/**
* The Class AddRoutingConnectionFeature.
*/
@@ -365,7 +623,7 @@ public class DefaultConnectionRouter extends AbstractConnectionRouter {
connection.getBendpoints().add(route.get(i));
}
- peService.setPropertyValue(connection, CONNECTION, "" + route.id); //$NON-NLS-1$
+ peService.setPropertyValue(connection, CONNECTION, "" + route.getId()); //$NON-NLS-1$
Polyline connectionLine = Graphiti.getGaService().createPolyline(
connection);

Back to the top