blob: 6f0293d2ef3b8d81ef96f10fcc739ea6a8dd3969 [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2019 CEA LIST, and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Nicolas FAUVERGUE (CEA LIST) nicolas.fauvergue@cea.fr - Initial API and implementation
*
*****************************************************************************/
package org.eclipse.papyrus.interoperability.sysml16.sysml14.blackboxes.notation;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PrecisionPoint;
import org.eclipse.draw2d.geometry.Straight;
import org.eclipse.gmf.runtime.notation.Bounds;
import org.eclipse.gmf.runtime.notation.Connector;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.Edge;
import org.eclipse.gmf.runtime.notation.IdentityAnchor;
import org.eclipse.gmf.runtime.notation.LayoutConstraint;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.runtime.notation.NotationFactory;
import org.eclipse.gmf.runtime.notation.RelativeBendpoints;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.gmf.runtime.notation.datatype.RelativeBendpoint;
import org.eclipse.m2m.qvt.oml.blackbox.java.Operation;
import org.eclipse.m2m.qvt.oml.blackbox.java.Operation.Kind;
import org.eclipse.papyrus.infra.gmfdiag.tooling.runtime.linklf.AbsoluteBendpointsConvention;
/**
* This allows to define the needed methods of UML for the transformations.
*/
public class NotationBlackboxHelper {
/**
* This allows to remove an object from a collection.
*
* @param parentView
* The parent view.
* @param eObjectToRemove
* The object to remove from the collection.
*/
@Operation(kind = Kind.HELPER)
public void removeFromOwnerView(final View parentView, final View eObjectToRemove) {
if (null != parentView && eObjectToRemove instanceof View) {
if (parentView.getChildren().contains(eObjectToRemove)) {
parentView.removeChild(eObjectToRemove);
} else if (parentView instanceof Diagram && eObjectToRemove instanceof Edge && ((Diagram) parentView).getEdges().contains(eObjectToRemove)) {
((Diagram) parentView).removeEdge((Edge) eObjectToRemove);
}
}
}
/**
* This allows to create the bendpoint for the information flow.
*
* @param informationFlowEdge
* The information flow connector.
*/
@Operation(kind = Kind.HELPER)
public void createBendpointsForInformationFlow(final Connector informationFlowEdge) {
// Create bendpoints with (0, 0) as source and target
final RelativeBendpoints bendpoints = NotationFactory.eINSTANCE.createRelativeBendpoints();
final List<RelativeBendpoint> points = new ArrayList<>(2);
final Point point = new Point(0, 0);
points.add(AbsoluteBendpointsConvention.getInstance().createAbsoluteBendpointStoredAsRelative(point));
points.add(AbsoluteBendpointsConvention.getInstance().createAbsoluteBendpointStoredAsRelative(point));
bendpoints.setPoints(points);
informationFlowEdge.setBendpoints(bendpoints);
}
/**
* This allows to create the bendpoint for the association.
*
* @param associationEdge
* The association connector.
*/
@Operation(kind = Kind.HELPER)
public void createBendpointsForAssociation(final Connector associationEdge) {
// Get the source and target views
final View sourceView = associationEdge.getSource();
final View targetView = associationEdge.getTarget();
final RelativeBendpoints bendpoints = NotationFactory.eINSTANCE.createRelativeBendpoints();
final List<RelativeBendpoint> points = new ArrayList<>(2);
// Check if the source and target views are nodes
if (sourceView instanceof Node && targetView instanceof Node) {
// Initialization
int sourceX = 0;
int sourceY = 0;
int sourceWidth = 0;
int sourceHeight = 0;
int targetX = 0;
int targetY = 0;
int targetWidth = 0;
int targetHeight = 0;
// Get the source layout constraint values
LayoutConstraint sourceLayoutConstraint = ((Node) sourceView).getLayoutConstraint();
if (sourceLayoutConstraint instanceof Bounds) {
sourceX = ((Bounds) sourceLayoutConstraint).getX();
sourceY = ((Bounds) sourceLayoutConstraint).getY();
sourceWidth = ((Bounds) sourceLayoutConstraint).getWidth();
if (sourceWidth == 0) {
sourceWidth = 1;
}
sourceHeight = ((Bounds) sourceLayoutConstraint).getHeight();
if (sourceHeight == 0) {
sourceHeight = 1;
}
}
// Get the target layout constraint values
final LayoutConstraint targetLayoutConstraint = ((Node) targetView).getLayoutConstraint();
if (targetLayoutConstraint instanceof Bounds) {
targetX = ((Bounds) targetLayoutConstraint).getX();
targetY = ((Bounds) targetLayoutConstraint).getY();
targetWidth = ((Bounds) targetLayoutConstraint).getWidth();
if (targetWidth == 0) {
targetWidth = 1;
}
targetHeight = ((Bounds) targetLayoutConstraint).getHeight();
if (targetHeight == 0) {
targetHeight = 1;
}
}
if (sourceView == targetView) {
// If the source and the target are the same object, the bendpoints must be with the center of the shape
final Point point = new Point(sourceX + (sourceWidth / 2), sourceY + (sourceHeight / 2));
points.add(AbsoluteBendpointsConvention.getInstance().createAbsoluteBendpointStoredAsRelative(point));
points.add(AbsoluteBendpointsConvention.getInstance().createAbsoluteBendpointStoredAsRelative(point));
} else {
final Straight centerToCenterStraight = new Straight(new PrecisionPoint(sourceX + (sourceWidth / 2), sourceY + (sourceHeight / 2)), new PrecisionPoint(targetX + (targetWidth / 2), targetY + (targetHeight / 2)));
PrecisionPoint intersectPointForFirstRectangle = null;
PrecisionPoint intersectPointForSecondRectangle = null;
// Calculate the point of the intersection for the first node
final Straight rightFirstRectangleStraight = new Straight(new PrecisionPoint(sourceX + sourceWidth, sourceY), new PrecisionPoint(sourceX + sourceWidth, sourceY + sourceHeight));
if (rightFirstRectangleStraight.intersects(centerToCenterStraight)) {
intersectPointForFirstRectangle = rightFirstRectangleStraight.getIntersection(centerToCenterStraight).toPoint();
} else {
final Straight bottomFirstRectangleStraight = new Straight(new PrecisionPoint(sourceX, sourceY + sourceHeight), new PrecisionPoint(sourceX + sourceWidth, sourceY + sourceHeight));
if (bottomFirstRectangleStraight.intersects(centerToCenterStraight)) {
intersectPointForFirstRectangle = bottomFirstRectangleStraight.getIntersection(centerToCenterStraight).toPoint();
} else {
final Straight leftFirstRectangleStraight = new Straight(new PrecisionPoint(sourceX, sourceY), new PrecisionPoint(sourceX, sourceY + sourceHeight));
if (leftFirstRectangleStraight.intersects(centerToCenterStraight)) {
intersectPointForFirstRectangle = leftFirstRectangleStraight.getIntersection(centerToCenterStraight).toPoint();
} else {
final Straight topFirstRectangleStraight = new Straight(new PrecisionPoint(sourceX, sourceY), new PrecisionPoint(sourceX + sourceWidth, sourceY));
if (topFirstRectangleStraight.intersects(centerToCenterStraight)) {
intersectPointForFirstRectangle = topFirstRectangleStraight.getIntersection(centerToCenterStraight).toPoint();
}
}
}
}
// Calculate the point of the intersection for the second node
final Straight rightSecondRectangleStraight = new Straight(new PrecisionPoint(sourceX + sourceWidth, sourceY), new PrecisionPoint(sourceX + sourceWidth, sourceY + sourceHeight));
if (rightSecondRectangleStraight.intersects(centerToCenterStraight)) {
intersectPointForSecondRectangle = rightSecondRectangleStraight.getIntersection(centerToCenterStraight).toPoint();
} else {
final Straight bottomSecondRectangleStraight = new Straight(new PrecisionPoint(sourceX, sourceY + sourceHeight), new PrecisionPoint(sourceX + sourceWidth, sourceY + sourceHeight));
if (bottomSecondRectangleStraight.intersects(centerToCenterStraight)) {
intersectPointForSecondRectangle = bottomSecondRectangleStraight.getIntersection(centerToCenterStraight).toPoint();
} else {
final Straight leftSecondRectangleStraight = new Straight(new PrecisionPoint(sourceX, sourceY), new PrecisionPoint(sourceX, sourceY + sourceHeight));
if (leftSecondRectangleStraight.intersects(centerToCenterStraight)) {
intersectPointForSecondRectangle = leftSecondRectangleStraight.getIntersection(centerToCenterStraight).toPoint();
} else {
final Straight topSecondRectangleStraight = new Straight(new PrecisionPoint(sourceX, sourceY), new PrecisionPoint(sourceX + sourceWidth, sourceY));
if (topSecondRectangleStraight.intersects(centerToCenterStraight)) {
intersectPointForSecondRectangle = topSecondRectangleStraight.getIntersection(centerToCenterStraight).toPoint();
}
}
}
}
if (null != intersectPointForFirstRectangle && null != intersectPointForSecondRectangle) {
// If the intersections are found, create the correct source and target points
final Point sourcePoint = new Point(sourceX + sourceWidth, targetY + (targetHeight / 2));
final Point targetPoint = new Point(targetX, sourceY + (sourceHeight / 2));
points.add(AbsoluteBendpointsConvention.getInstance().createAbsoluteBendpointStoredAsRelative(sourcePoint));
points.add(AbsoluteBendpointsConvention.getInstance().createAbsoluteBendpointStoredAsRelative(targetPoint));
}
}
}
// If no points are created, create points to (0, 0)
if (points.isEmpty()) {
final Point point = new Point(0, 0);
points.add(AbsoluteBendpointsConvention.getInstance().createAbsoluteBendpointStoredAsRelative(point));
points.add(AbsoluteBendpointsConvention.getInstance().createAbsoluteBendpointStoredAsRelative(point));
}
bendpoints.setPoints(points);
associationEdge.setBendpoints(bendpoints);
}
/**
* This allows to create the bendpoint for the association Tether edge.
*
* @param associationTetherEdge
* The association Tether edge.
*/
@Operation(kind = Kind.HELPER)
public void createBendpointsForAssociationTetherEdge(final Connector associationTetherEdge) {
// Create bendpoints with (-50, -49) as source and target
final RelativeBendpoints bendpoints = NotationFactory.eINSTANCE.createRelativeBendpoints();
final List<RelativeBendpoint> points = new ArrayList<>(2);
final Point point = new Point(-50, -49);
points.add(new RelativeBendpoint(point.x, point.y, 0, 0));
points.add(new RelativeBendpoint(point.x, point.y, 0, 0));
bendpoints.setPoints(points);
associationTetherEdge.setBendpoints(bendpoints);
// Create the identityAnchor in the middle of the association
final IdentityAnchor identityAnchor = NotationFactory.eINSTANCE.createIdentityAnchor();
identityAnchor.setId("(0.5,0.5)");
associationTetherEdge.setSourceAnchor(identityAnchor);
}
}