blob: 8a9da321a757f2d6570aaa5e952fd7cb6eb849b1 [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2015 CEA LIST.
*
*
* 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:
* Sebastien Revol (CEA LIST) sebastien.revol@cea.fr - Initial API and implementation
* Vincent Lorenzo (CEa LIST) vincent.lorenzo@cea.fr - bugs 496176, 499237
*****************************************************************************/
package org.eclipse.papyrus.interoperability.rpy.blackboxes;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.gmf.runtime.draw2d.ui.geometry.LineSeg;
import org.eclipse.gmf.runtime.draw2d.ui.geometry.LineSeg.KeyPoint;
import org.eclipse.gmf.runtime.notation.Connector;
import org.eclipse.gmf.runtime.notation.IdentityAnchor;
import org.eclipse.gmf.runtime.notation.NotationFactory;
import org.eclipse.gmf.runtime.notation.RelativeBendpoints;
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.interoperability.rpy.geometry.rpygeometry.Point;
import org.eclipse.papyrus.interoperability.rpy.geometry.rpygeometry.RpyGeometryFactory;
import org.eclipse.papyrus.interoperability.rpy.geometry.rpygeometry.RpyShape;
import org.eclipse.papyrus.interoperability.rpy.geometry.utils.RpyShapeOperations;
import org.eclipse.papyrus.interoperability.rpy.rpymetamodel.CGIAnchor;
import org.eclipse.papyrus.interoperability.rpy.rpymetamodel.CGIAssociationEnd;
import org.eclipse.papyrus.interoperability.rpy.rpymetamodel.CGIDiagramFrame;
import org.eclipse.papyrus.interoperability.rpy.rpymetamodel.CGIObjectLink;
import org.eclipse.papyrus.interoperability.rpy.rpymetamodel.GraphElementsType;
/**
* @author sr246418
*
*/
public class Rpy2PapyrusNotationBlackboxes {
/** the size of the transform field */
public static final int M_TRANSFORM_SIZE = 6;
/** the index of intersting value in m transform */
public static final int M_TRANSFORM_X_RATIO_INDEX = 0;
public static final int M_TRANSFORM_Y_RATIO_INDEX = 3;
public static final int M_TRANSFORM_X_POSITION_INDEX = 4;
public static final int M_TRANSFORM_Y_POSITION_INDEX = 5;
/** the index of the x and y value for each points of the rectangle */
public static final int M_POLYGON__RECTANGLE_NB_POINTS_INDEX = 0;
/** the index of the x and y value for each points of the rectangle */
public static final int M_POLYGON__RECTANGLE_TOP_LEFT_CORNER_X_INDEX = 1;
public static final int M_POLYGON__RECTANGLE_TOP_LEFT_CORNER_Y_INDEX = 2;
public static final int M_POLYGON__RECTANGLE_BOTTOM_LEFT_CORNER_X_INDEX = 3;
public static final int M_POLYGON__RECTANGLE_BOTTOM_LEFT_CORNER_Y_INDEX = 4;
public static final int M_POLYGON__RECTANGLE_BOTTOM_RIGHT_CORNER_X_INDEX = 5;
public static final int M_POLYGON__RECTANGLE_BOTTOM_RIGHT_CORNER__Y_INDEX = 6;
public static final int M_POLYGON__RECTANGLE_TOP_RIGHT_CORNER_X_INDEX = 7;
public static final int M_POLYGON__RECTANGLE_TOP_RIGHT_CORNER_Y_INDEX = 8;
/** X and Y indexes for a point in an array */
public static final int X_INDEX = 0;
public static final int Y_INDEX = 1;
/** code returned when we are not able to get the wanted value */
public static final int ERROR_CODE = Integer.MAX_VALUE;
/** names of structural feature */
public static final String M_TRANSFORM = "m_transform"; //$NON-NLS-1$
public static final String M_POLYGON = "m_polygon"; //$NON-NLS-1$
public static final String M_pPARENT = "m_pParent"; //$NON-NLS-1$
// TODO : try to link me to GMF value!
private static final int MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS = -643984;
@Operation(kind = Kind.HELPER)
public boolean contains(final String aString, final String aPotentialSubString) {
if (null == aString || aPotentialSubString == null) {
return false;
}
return aString.contains(aPotentialSubString);
}
// TODO add GMF source and target object to get their size and location ?
// 0 : source, 1 : target, 2, ... bendpoints if required
// TODO : we advice to manage anchor and bendpoints in the same method, to be able to make required adjutment
/**
* @param
* a
* Rpy association
* @param
* result
* @return a list, where the 2 first values are the source anchor and the target anchors.
*
* TODO update documentation when we will manage bendpoint too in the same method
* //TODO speak about the magic number
* //TODO try to set one anchor term to 0 or 1 each time
* //TODO : property m_line_style is not yet exploited : 0 is straight, 2 is rectilinear
*
*/
@Operation(kind = Kind.QUERY)
public void addAnchorsAndBendpoints(Object association, Connector result) {
if (!isARpyLink(association)) {
return;
}
// 1. we need to get all in absolute position
// find source and target anchor in absolute location
final List<String> rpySourceAnchorAsString = getM_SourcePort(association);
final List<String> rpyTargetAnchorAsString = getM_TargetPort(association);
final GraphElementsType sourceGraphicalObject = getM_pSource(association);
final GraphElementsType targetGraphicalObject = getM_pTarget(association);
final RpyShape sourceShape = RpyShapeOperations.createRpyShape(sourceGraphicalObject);
final RpyShape targetShape = RpyShapeOperations.createRpyShape(targetGraphicalObject);
final Point rpySourceAnchor = RpyGeometryFactory.eINSTANCE.createPoint();
rpySourceAnchor.setX(Double.valueOf(rpySourceAnchorAsString.get(0)));
rpySourceAnchor.setY(Double.valueOf(rpySourceAnchorAsString.get(1)));
final Point rpySourceAnchorInAbsolute = sourceShape.getTransform().multiply(rpySourceAnchor);
final Point rpyTargetAnchor = RpyGeometryFactory.eINSTANCE.createPoint();
rpyTargetAnchor.setX(Double.valueOf(rpyTargetAnchorAsString.get(0)));
rpyTargetAnchor.setY(Double.valueOf(rpyTargetAnchorAsString.get(1)));
final Point rpyTargetAnchorInAbsolute = targetShape.getTransform().multiply(rpyTargetAnchor);
// 2. determine bendpoints in absolute location
final List<String> rpyBendpointsAsString = getM_arrow(association);
final List<Point> rpyBendpointsInAbsolute = new ArrayList<Point>();
if (rpyBendpointsAsString.size() > 0) {
for (int i = 1; i < Integer.valueOf(rpyBendpointsAsString.get(0)) * 2; i = i + 2) {
Point newPoint = RpyGeometryFactory.eINSTANCE.createPoint();
newPoint.setX(Double.valueOf(rpyBendpointsAsString.get(i)));
newPoint.setY(Double.valueOf(rpyBendpointsAsString.get(i + 1)));
rpyBendpointsInAbsolute.add(newPoint);
}
}
// 3. here we get the source anchor, the target anchor and the bendpoints in absolute location
// it is here we could do some adjustment to fix round errors
// TODO : fix round errors!?
// /!\ fixing error could make problems for link linked to link ?
// bendpoint could be not in the good location, if we add/remove an offset to the compartemnt contents!
// 4. we can now determine source anchor, target anchor and bendpoints
final Point sourceAnchorInRelative = RpyGeometryFactory.eINSTANCE.createPoint();
sourceAnchorInRelative.setX(rpySourceAnchorInAbsolute.getX() - sourceShape.getAbsolutePosition().getX());
sourceAnchorInRelative.setY(rpySourceAnchorInAbsolute.getY() - sourceShape.getAbsolutePosition().getY());
final Point targetAnchorInRelative = RpyGeometryFactory.eINSTANCE.createPoint();
targetAnchorInRelative.setX(rpyTargetAnchorInAbsolute.getX() - targetShape.getAbsolutePosition().getX());
targetAnchorInRelative.setY(rpyTargetAnchorInAbsolute.getY() - targetShape.getAbsolutePosition().getY());
final Point firstBendpoint = RpyGeometryFactory.eINSTANCE.createPoint();
firstBendpoint.setX(rpySourceAnchorInAbsolute.getX());
firstBendpoint.setY(rpySourceAnchorInAbsolute.getY());
final Point lastBendpoint = RpyGeometryFactory.eINSTANCE.createPoint();
lastBendpoint.setX(rpyTargetAnchorInAbsolute.getX());
lastBendpoint.setY(rpyTargetAnchorInAbsolute.getY());
// we create the bendpoints list
List<RelativeBendpoint> gmfBendpoints = new ArrayList<RelativeBendpoint>();
// source bendpoints
gmfBendpoints.add(new RelativeBendpoint(firstBendpoint.getIntX(), firstBendpoint.getIntY(), MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS, MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS));
// intermediate bendpoints
for (Point current : rpyBendpointsInAbsolute) {
gmfBendpoints.add(new RelativeBendpoint(current.getIntX(), current.getIntY(), MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS, MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS));
}
// last bendpoints
gmfBendpoints.add(new RelativeBendpoint(lastBendpoint.getIntX(), lastBendpoint.getIntY(), MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS, MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS));
// we register the bendpoints into the connector
RelativeBendpoints bendpoints12 = NotationFactory.eINSTANCE.createRelativeBendpoints();
bendpoints12.setPoints(gmfBendpoints);
result.setBendpoints(bendpoints12);
IdentityAnchor sourceAnchor = NotationFactory.eINSTANCE.createIdentityAnchor();
sourceAnchor.setId(getAnchorFromAbsolutePosition(sourceShape, sourceAnchorInRelative));
IdentityAnchor targetAnchor = NotationFactory.eINSTANCE.createIdentityAnchor();
targetAnchor.setId(getAnchorFromAbsolutePosition(targetShape, targetAnchorInRelative));
result.setSourceAnchor(sourceAnchor);
result.setTargetAnchor(targetAnchor);
//
// TODO : rewritte anchor code
// String sourceAnchor = getAnchorFromAbsolutePosition(sourceShape, rpySourceAnchorAsString);
// String targetAnchor = getAnchorFromAbsolutePosition(targetShape, rpyTargetAnchorAsString);
// List<String> returnedValues = new ArrayList<>();
// returnedValues.add(sourceAnchor);
// returnedValues.add(targetAnchor);
//
// return returnedValues;
}
/**
*
* @param anObject
* an object
* @return
* <code>true</code> if the object can be considered as a rpy link
*/
private boolean isARpyLink(final Object anObject) {
if (getM_pSource(anObject) != null && getM_pTarget(anObject) != null && getM_SourcePort(anObject).size() == 2 && getM_TargetPort(anObject).size() == 2) {
return true;
}
return false;
}
private List<String> getM_arrow(Object anObject) {
if (anObject instanceof CGIObjectLink) {
return ((CGIObjectLink) anObject).getM_arrow();
} else if (anObject instanceof CGIAnchor) {
return ((CGIAnchor) anObject).getM_arrow();
} else if (anObject instanceof CGIAssociationEnd) {
return ((CGIAssociationEnd) anObject).getM_arrow();
}
return Collections.emptyList();
}
private GraphElementsType getM_pSource(Object anObject) {
if (anObject instanceof CGIObjectLink) {
return (GraphElementsType) ((CGIObjectLink) anObject).getM_pSource();
} else if (anObject instanceof CGIAnchor) {
return (GraphElementsType) ((CGIAnchor) anObject).getM_pSource();
} else if (anObject instanceof CGIAssociationEnd) {
return (GraphElementsType) ((CGIAssociationEnd) anObject).getM_pSource();
}
return null;
}
private GraphElementsType getM_pTarget(Object anObject) {
if (anObject instanceof CGIObjectLink) {
return (GraphElementsType) ((CGIObjectLink) anObject).getM_pTarget();
} else if (anObject instanceof CGIAnchor) {
return (GraphElementsType) ((CGIAnchor) anObject).getM_pTarget();
} else if (anObject instanceof CGIAssociationEnd) {
return (GraphElementsType) ((CGIAssociationEnd) anObject).getM_pTarget();
}
return null;
}
private List<String> getM_SourcePort(Object anObject) {
if (anObject instanceof CGIObjectLink) {
return ((CGIObjectLink) anObject).getM_SourcePort();
} else if (anObject instanceof CGIAnchor) {
return ((CGIAnchor) anObject).getM_SourcePort();
} else if (anObject instanceof CGIAssociationEnd) {
return ((CGIAssociationEnd) anObject).getM_SourcePort();
}
return Collections.emptyList();
}
private List<String> getM_TargetPort(Object anObject) {
if (anObject instanceof CGIObjectLink) {
return ((CGIObjectLink) anObject).getM_TargetPort();
} else if (anObject instanceof CGIAnchor) {
return ((CGIAnchor) anObject).getM_TargetPort();
} else if (anObject instanceof CGIAssociationEnd) {
return ((CGIAssociationEnd) anObject).getM_TargetPort();
}
return Collections.emptyList();
}
/** This method has been developed (not yet finished and not yet usable) to be able to create link on link */
@Operation(kind = Kind.QUERY)
// TODO : finish me!
public void addAnchorsAndBendpoints_V2_FOR_LinkONLink(CGIAnchor association, Connector result) {
// 1. we need to get all in absolute position
// find source and target anchor in absolute location
final List<String> rpySourceAnchorAsString = association.getM_SourcePort();
final List<String> rpyTargetAnchorAsString = association.getM_TargetPort();
final GraphElementsType sourceGraphicalObject = (GraphElementsType) association.getM_pSource();
final GraphElementsType targetGraphicalObject = (GraphElementsType) association.getM_pTarget();
Point newTargetAnchorInAbsolute = null;// RpyGeometryFactory.eINSTANCE.createPoint();
// ------------------this part of the code has been done to be able to create anchor on a link (comment link linked to an other link!!!!-----
if (targetGraphicalObject instanceof CGIObjectLink) {// we are connected on a link, so rpyTargetAnchorAsString could have a first value in % and the second one seem be 0
CGIObjectLink link = ((CGIObjectLink) targetGraphicalObject);
Connector tmp = NotationFactory.eINSTANCE.createConnector();
addAnchorsAndBendpoints(link, tmp);
// 1. calculate the full length of the link:
final RelativeBendpoints bendpoints = (RelativeBendpoints) tmp.getBendpoints();
double length = 0;
List<LineSeg> linesSegs = new ArrayList<LineSeg>();
// Iterator<RelativeBendpoint> iter = bendpoints.getPoints().iterator();
List<Double> cumulatedLength = new ArrayList<>();
for (int i = 1; i < bendpoints.getPoints().size(); i++) {
RelativeBendpoint pt1 = (RelativeBendpoint) bendpoints.getPoints().get(i - 1);
RelativeBendpoint pt2 = (RelativeBendpoint) bendpoints.getPoints().get(i);
linesSegs.add(new LineSeg(new org.eclipse.draw2d.geometry.Point(pt1.getSourceX(), pt1.getSourceY()), new org.eclipse.draw2d.geometry.Point(pt2.getSourceX(), pt2.getSourceY())));
}
for (LineSeg lineSeg : linesSegs) {
length += lineSeg.length();
cumulatedLength.add(Double.valueOf(length));
}
double percentage = Double.valueOf(rpyTargetAnchorAsString.get(0));
double wantedLength = length * percentage / 100.00;
int wantedLineSeg = -1;
int iter = 0;
while (wantedLineSeg == -1 && iter < cumulatedLength.size()) {
if (cumulatedLength.get(iter) > wantedLength) {
// i is the index of the lineseg on which the good length is obtained
wantedLineSeg = iter;
}
}
double needToCrossOnThisLineSeg = -1;
if (iter == 0) {
needToCrossOnThisLineSeg = wantedLength;
} else {
needToCrossOnThisLineSeg = wantedLength - cumulatedLength.get(wantedLineSeg - 1);
}
LineSeg w = linesSegs.get(iter);
double percentage12 = 100 * needToCrossOnThisLineSeg / linesSegs.get(iter).length();
double xOffset = ((double) w.getTerminus().x - (double) w.getOrigin().x) * percentage12 / 100.0;
double yOffset = ((double) w.getTerminus().y - (double) w.getOrigin().y) * percentage12 / 100.0;
newTargetAnchorInAbsolute = RpyGeometryFactory.eINSTANCE.createPoint();
newTargetAnchorInAbsolute.setX(w.getOrigin().x + xOffset);
newTargetAnchorInAbsolute.setY(w.getOrigin().y + yOffset);
org.eclipse.draw2d.geometry.Point ptResult = new org.eclipse.draw2d.geometry.Point();
KeyPoint toto = KeyPoint.ORIGIN;
w.pointOn((long) needToCrossOnThisLineSeg, toto, ptResult);
// double tmpLength = 0;
// Iterator<LineSeg> iter = linesSegs.iterator();
//
// while (tmpLength < wantedLength && iter.hasNext()) {
// LineSeg current = iter.next();
// tmpLength += current.length();
// }
//
// int segIndex = -1;
// for (int i = 0; i < cumulatedLength.size(); i++) {
// if (wantedLength > cumulatedLength.get(i)) {
// segIndex = i - 1;
// }
// }
// double requiredLengthOnThisSeg = wantedLength - cumulatedLength.get(segIndex);
int j = 0;
j++;
Connector c = null;
// c.
}
final RpyShape sourceShape = RpyShapeOperations.createRpyShape(sourceGraphicalObject);
final RpyShape targetShape = RpyShapeOperations.createRpyShape(targetGraphicalObject);
final Point rpySourceAnchor = RpyGeometryFactory.eINSTANCE.createPoint();
rpySourceAnchor.setX(Double.valueOf(rpySourceAnchorAsString.get(0)));
rpySourceAnchor.setY(Double.valueOf(rpySourceAnchorAsString.get(1)));
final Point rpySourceAnchorInAbsolute = sourceShape.getTransform().multiply(rpySourceAnchor);
final Point rpyTargetAnchor = RpyGeometryFactory.eINSTANCE.createPoint();
rpyTargetAnchor.setX(Double.valueOf(rpyTargetAnchorAsString.get(0)));
rpyTargetAnchor.setY(Double.valueOf(rpyTargetAnchorAsString.get(1)));
final Point rpyTargetAnchorInAbsolute;
if (newTargetAnchorInAbsolute == null) {
rpyTargetAnchorInAbsolute = targetShape.getTransform().multiply(rpyTargetAnchor);
} else {
rpyTargetAnchorInAbsolute = newTargetAnchorInAbsolute;
}
// 2. determine bendpoints in absolute location
final List<String> rpyBendpointsAsString = association.getM_arrow();
final List<Point> rpyBendpointsInAbsolute = new ArrayList<Point>();
if (rpyBendpointsAsString.size() > 0) {
for (int i = 1; i < Integer.valueOf(rpyBendpointsAsString.get(0)) * 2; i = i + 2) {
Point newPoint = RpyGeometryFactory.eINSTANCE.createPoint();
newPoint.setX(Double.valueOf(rpyBendpointsAsString.get(i)));
newPoint.setY(Double.valueOf(rpyBendpointsAsString.get(i + 1)));
rpyBendpointsInAbsolute.add(newPoint);
}
}
// 3. here we get the source anchor, the target anchor and the bendpoints in absolute location
// it is here we could do some adjustment to fix round errors
// TODO : fix round errors!?
// /!\ fixing error could make problems for link linked to link ?
// bendpoint could be not in the good location, if we add/remove an offset to the compartemnt contents!
// 4. we can now determine source anchor, target anchor and bendpoints
final Point sourceAnchorInRelative = RpyGeometryFactory.eINSTANCE.createPoint();
sourceAnchorInRelative.setX(rpySourceAnchorInAbsolute.getX() - sourceShape.getAbsolutePosition().getX());
sourceAnchorInRelative.setY(rpySourceAnchorInAbsolute.getY() - sourceShape.getAbsolutePosition().getY());
final Point targetAnchorInRelative = RpyGeometryFactory.eINSTANCE.createPoint();
targetAnchorInRelative.setX(rpyTargetAnchorInAbsolute.getX() - targetShape.getAbsolutePosition().getX());
targetAnchorInRelative.setY(rpyTargetAnchorInAbsolute.getY() - targetShape.getAbsolutePosition().getY());
final Point firstBendpoint = RpyGeometryFactory.eINSTANCE.createPoint();
firstBendpoint.setX(rpySourceAnchorInAbsolute.getX());
firstBendpoint.setY(rpySourceAnchorInAbsolute.getY());
final Point lastBendpoint = RpyGeometryFactory.eINSTANCE.createPoint();
lastBendpoint.setX(rpyTargetAnchorInAbsolute.getX());
lastBendpoint.setY(rpyTargetAnchorInAbsolute.getY());
// we create the bendpoints list
List<RelativeBendpoint> gmfBendpoints = new ArrayList<RelativeBendpoint>();
// source bendpoints
gmfBendpoints.add(new RelativeBendpoint(firstBendpoint.getIntX(), firstBendpoint.getIntY(), MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS, MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS));
// intermediate bendpoints
for (Point current : rpyBendpointsInAbsolute) {
gmfBendpoints.add(new RelativeBendpoint(current.getIntX(), current.getIntY(), MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS, MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS));
}
// last bendpoints
gmfBendpoints.add(new RelativeBendpoint(lastBendpoint.getIntX(), lastBendpoint.getIntY(), MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS, MAGIC_NUMBER_FOR_ABSOLUTE_BENDPOINTS));
// we register the bendpoints into the connector
RelativeBendpoints bendpoints12 = NotationFactory.eINSTANCE.createRelativeBendpoints();
bendpoints12.setPoints(gmfBendpoints);
result.setBendpoints(bendpoints12);
IdentityAnchor sourceAnchor = NotationFactory.eINSTANCE.createIdentityAnchor();
sourceAnchor.setId(getAnchorFromAbsolutePosition(sourceShape, sourceAnchorInRelative));
IdentityAnchor targetAnchor = NotationFactory.eINSTANCE.createIdentityAnchor();
targetAnchor.setId(getAnchorFromAbsolutePosition(targetShape, targetAnchorInRelative));
result.setSourceAnchor(sourceAnchor);
result.setTargetAnchor(targetAnchor);
}
protected String getAnchorFromAbsolutePosition(RpyShape shape, Point point) {
float newxRatio = 0;// = new Float(xPort) / new Float(shape.getWidth());
float newyRatio = 0;// = new Float(yPort) / new Float(shape.getHeight());
newxRatio = new Float(point.getX()) / new Float(shape.getWidth());
newyRatio = new Float(point.getY()) / new Float(shape.getHeight());
if (newxRatio > 1) {
newxRatio = 1;
}
if (newyRatio > 1) {
newyRatio = 1;
}
String id = "(" + newxRatio + "," + newyRatio + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
return id;
}
@Deprecated
protected String getAnchorFromAbsolutePosition(RpyShape shape, List<String> port) {
Point point = RpyGeometryFactory.eINSTANCE.createPoint();
point.setX(Double.valueOf(port.get(0)));
point.setY(Double.valueOf(port.get(1)));
Point res = shape.getTransform().multiply(point);
res.setX(res.getX() - shape.getAbsolutePosition().getX());
res.setY(res.getY() - shape.getAbsolutePosition().getY());
double[] topLeft = new double[] { shape.getParentRelativePosition().getX(), shape.getParentRelativePosition().getY() };
double[] topRight = new double[] { shape.getParentRelativePosition().getX() + (double) shape.getWidth(), shape.getParentRelativePosition().getY() };
double[] bottomLeft = new double[] { shape.getParentRelativePosition().getX(), shape.getParentRelativePosition().getY() + (double) shape.getHeight() };
double xPort = Double.parseDouble(port.get(0));
if (xPort < topLeft[X_INDEX]) {
xPort = topLeft[X_INDEX];
}
if (xPort > topRight[X_INDEX]) {
xPort = topRight[X_INDEX];
}
double yPort = Double.parseDouble(port.get(1));
if (yPort < topLeft[Y_INDEX]) {
yPort = topLeft[Y_INDEX];
}
if (yPort > bottomLeft[Y_INDEX]) {
yPort = bottomLeft[Y_INDEX];
}
float newxRatio = new Float(xPort) / new Float(shape.getWidth());
float newyRatio = new Float(yPort) / new Float(shape.getHeight());
newxRatio = new Float(res.getX()) / new Float(shape.getWidth());
newyRatio = new Float(res.getY()) / new Float(shape.getHeight());
if (newxRatio > 1) {
newxRatio = 1;
}
if (newyRatio > 1) {
newyRatio = 1;
}
String id = "(" + newxRatio + "," + newyRatio + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
return id;
}
@Operation(kind = Kind.HELPER)
public String getAnchorId(List<String> polygon, List<String> transform, List<String> port) {
// int[] topLeft = new int[] { Integer.parseInt(polygon.get(1)), Integer.parseInt(polygon.get(2)) };
int[] topLeft = new int[] { Integer.parseInt(polygon.get(M_POLYGON__RECTANGLE_TOP_LEFT_CORNER_X_INDEX)), Integer.parseInt(polygon.get(M_POLYGON__RECTANGLE_TOP_LEFT_CORNER_Y_INDEX)) };
int[] topRight = new int[] { Integer.parseInt(polygon.get(M_POLYGON__RECTANGLE_TOP_RIGHT_CORNER_X_INDEX)), Integer.parseInt(polygon.get(M_POLYGON__RECTANGLE_TOP_RIGHT_CORNER_Y_INDEX)) };
int[] bottomLeft = new int[] { Integer.parseInt(polygon.get(M_POLYGON__RECTANGLE_BOTTOM_LEFT_CORNER_X_INDEX)), Integer.parseInt(polygon.get(M_POLYGON__RECTANGLE_BOTTOM_LEFT_CORNER_Y_INDEX)) };
int xPort = Integer.parseInt(port.get(0));
if (xPort < topLeft[X_INDEX]) {
xPort = topLeft[X_INDEX];
}
if (xPort > topRight[X_INDEX]) {
xPort = topRight[X_INDEX];
}
int yPort = Integer.parseInt(port.get(1));
if (yPort < topLeft[Y_INDEX]) {
yPort = topLeft[Y_INDEX];
}
if (yPort > bottomLeft[Y_INDEX]) {
yPort = bottomLeft[Y_INDEX];
}
float newxRatio = new Float(xPort) / new Float(getRelativeWidth(topRight[0], topLeft[0]));
float newyRatio = new Float(yPort) / new Float(getRelativeHeight(bottomLeft[1], topLeft[1]));
if (newxRatio > 1) {
newxRatio = 1;
}
if (newyRatio > 1) {
newyRatio = 1;
}
String id = "(" + newxRatio + "," + newyRatio + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
return id;
}
public static int getRelativeHeight(int a, int b) {
return (a - b);
}
public static int getRelativeWidth(int a, int b) {
return (a - b);
}
/**
*
* @param polygon
* @param transform
* @return
*
* @deprecated since 0.7
*/
@Deprecated
@Operation(kind = Kind.HELPER)
public int getStateHeight(List<String> polygon, List<String> transform) {
// State Partition (top left, top right, bottom right, bottom left) not
// same for classes
int[] topLeft = new int[] { Integer.parseInt(polygon.get(1)), Integer.parseInt(polygon.get(2)) };
int[] topRight = new int[] { Integer.parseInt(polygon.get(3)), Integer.parseInt(polygon.get(4)) };
int[] bottomRight = new int[] { Integer.parseInt(polygon.get(5)), Integer.parseInt(polygon.get(6)) };
int[] bottomLeft = new int[] { Integer.parseInt(polygon.get(7)), Integer.parseInt(polygon.get(8)) };
float xRatio = Float.parseFloat(transform.get(0));
float yRatio = Float.parseFloat(transform.get(3));
return Math.round(yRatio * (bottomLeft[1] - topLeft[1]));
}
/**
*
* @param polygon
* @param transform
* @return
*
* @deprecated since 0.7
*/
@Deprecated
@Operation(kind = Kind.HELPER)
public int getStateWidth(List<String> polygon, List<String> transform) {
int[] topLeft = new int[] { Integer.parseInt(polygon.get(1)), Integer.parseInt(polygon.get(2)) };
int[] topRight = new int[] { Integer.parseInt(polygon.get(3)), Integer.parseInt(polygon.get(4)) };
int[] bottomRight = new int[] { Integer.parseInt(polygon.get(5)), Integer.parseInt(polygon.get(6)) };
int[] bottomLeft = new int[] { Integer.parseInt(polygon.get(7)), Integer.parseInt(polygon.get(8)) };
float xRatio = Float.parseFloat(transform.get(0));
float yRatio = Float.parseFloat(transform.get(3));
return Math.round(xRatio * (topRight[0] - topLeft[0]));
}
/**
*
* @param polygon
* @param transform
* @return
*
* @deprecated since 0.7
*/
@Deprecated
@Operation(kind = Kind.HELPER)
public int getClassHeight(List<String> polygon, List<String> transform) {
// State Partition (top left, top right, bottom right, bottom left) not
// same for classes
int[] topLeft = new int[] { Integer.parseInt(polygon.get(1)), Integer.parseInt(polygon.get(2)) };
int[] bottomLeft = new int[] { Integer.parseInt(polygon.get(3)), Integer.parseInt(polygon.get(4)) };
int[] bottomRight = new int[] { Integer.parseInt(polygon.get(5)), Integer.parseInt(polygon.get(6)) };
int[] topRight = new int[] { Integer.parseInt(polygon.get(7)), Integer.parseInt(polygon.get(8)) };
float xRatio = Float.parseFloat(transform.get(0));
float yRatio = Float.parseFloat(transform.get(3));
return Math.round(yRatio * (bottomLeft[1] - topLeft[1]));
}
@Operation(kind = Kind.HELPER)
public int getClassWidth(List<String> polygon, List<String> transform) {
int[] topLeft = new int[] { Integer.parseInt(polygon.get(1)), Integer.parseInt(polygon.get(2)) };
int[] bottomLeft = new int[] { Integer.parseInt(polygon.get(3)), Integer.parseInt(polygon.get(4)) };
int[] bottomRight = new int[] { Integer.parseInt(polygon.get(5)), Integer.parseInt(polygon.get(6)) };
int[] topRight = new int[] { Integer.parseInt(polygon.get(7)), Integer.parseInt(polygon.get(8)) };
float xRatio = Float.parseFloat(transform.get(0));
float yRatio = Float.parseFloat(transform.get(3));
return Math.round(xRatio * (topRight[0] - topLeft[0]));
}
/**
*
* @param m_polygon
* the field polygon
* @param m_transform
* the field transform
* @return the width of the object
* @deprecated since 0.7. use others method instead
*/
@Deprecated
public int getWidth(List<String> m_polygon, List<String> m_transform) {
int[] topLeft = new int[] { Integer.parseInt(m_polygon.get(1)), Integer.parseInt(m_polygon.get(2)) };
// int[] bottomLeft = new int[] { Integer.parseInt(polygon.get(3)), Integer.parseInt(polygon.get(4)) };
// int[] bottomRight = new int[] { Integer.parseInt(polygon.get(5)), Integer.parseInt(polygon.get(6)) };
int[] topRight = new int[] { Integer.parseInt(m_polygon.get(7)), Integer.parseInt(m_polygon.get(8)) };
float xRatio = Float.parseFloat(m_transform.get(0));
// float yRatio = Float.parseFloat(transform.get(3));
return Math.round(xRatio * (topRight[0] - topLeft[0]));
}
/**
*
* @param polygon
* the field polygon
* @param transform
* the field transform
* @return the height of the object
* @deprecated since 0.7. use others method instead
*/
@Deprecated
public int getHeight(List<String> polygon, List<String> transform) {
int[] topLeft = new int[] { Integer.parseInt(polygon.get(1)), Integer.parseInt(polygon.get(2)) };
int[] bottomLeft = new int[] { Integer.parseInt(polygon.get(3)), Integer.parseInt(polygon.get(4)) };
// int[] bottomRight = new int[] { Integer.parseInt(polygon.get(5)), Integer.parseInt(polygon.get(6)) };
// int[] topRight = new int[] { Integer.parseInt(polygon.get(7)), Integer.parseInt(polygon.get(8)) };
// float xRatio = Float.parseFloat(transform.get(0));
float yRatio = Float.parseFloat(transform.get(3));
return Math.round(yRatio * (bottomLeft[1] - topLeft[1]));
}
/**
*
* @param element
* a graphical element
* @return
* the X ratio to apply on the object to get its width
*/
@Operation(kind = Kind.HELPER)
public float get_X_Ratio(GraphElementsType element) {
float result = 1;
final List<String> mTransform = getTransformList(element);
if (null != mTransform && mTransform.size() == M_TRANSFORM_SIZE) {
result = Float.parseFloat(mTransform.get(M_TRANSFORM_X_RATIO_INDEX));
final GraphElementsType parent = getParent(element);
if (!(parent instanceof CGIDiagramFrame)) {
result = result * get_X_Ratio(parent);
}
}
return result;
}
/**
*
* @param element
* a graphical element
* @return
* the X ratio to apply on the object to get its height
*/
@Operation(kind = Kind.HELPER)
public float get_Y_Ratio(final GraphElementsType element) {
float result = 1;
final List<String> mTransform = getTransformList(element);
if (null != mTransform && mTransform.size() == M_TRANSFORM_SIZE) {
result = Float.parseFloat(mTransform.get(M_TRANSFORM_Y_RATIO_INDEX));
final GraphElementsType parent = getParent(element);
if (!(parent instanceof CGIDiagramFrame)) {
result = result * get_Y_Ratio(parent);
}
}
return result;
}
/**
*
* @param element
* a graphical element
* @return
* the value of the m_pParent field if it exits for the given object or <code>null</code> in other case
*/
private final GraphElementsType getParent(final GraphElementsType element) {
final EStructuralFeature paretnFeature = element.eClass().getEStructuralFeature("m_pParent"); //$NON-NLS-1$
if (null != paretnFeature) {
Object value = element.eGet(paretnFeature);
if (value instanceof GraphElementsType) {
return (GraphElementsType) value;
}
}
return null;
}
/**
*
* @param element
* a graphical element
* @return
* the value of the m_Transform field if it exits for the given object or <code>null</code> in other case
*/
@SuppressWarnings("unchecked")
protected final List<String> getTransformList(final GraphElementsType element) {
List<String> returnedValues = new ArrayList<String>();
final EStructuralFeature mTransformFeature = element.eClass().getEStructuralFeature(M_TRANSFORM);
if (null != mTransformFeature) {
final Object mTransformValue = element.eGet(mTransformFeature);
if (mTransformValue instanceof List<?>) {
returnedValues.addAll((List<String>) mTransformValue);
}
}
// We can consider number in e as 0;
List<String> toReturn = new ArrayList<String>();
if (returnedValues.size() != 6) {
for (int i = 0; i < returnedValues.size(); i++) {
String tmp = returnedValues.get(i);
if (tmp.startsWith("e")) {
continue;
}
if (!tmp.startsWith("e") && returnedValues.size() > (i + 1)) {
String tmp2 = returnedValues.get(i + 1);
if (tmp2.startsWith("e")) {
tmp += tmp2;
}
}
toReturn.add(tmp);
}
returnedValues = toReturn;
}
for (int i = 0; i < returnedValues.size(); i++) {
String tmp = returnedValues.get(i);
if (tmp.contains("e-")) {
returnedValues.set(i, "0");
}
}
return returnedValues;
}
/**
*
* @param element
* a graphical element
* @return
* the value of the m_Polygon field if it exits for the given object or <code>null</code> in other case
*/
@SuppressWarnings("unchecked")
protected final List<String> getPolygonList(GraphElementsType element) {
final EStructuralFeature mPolygonFeature = element.eClass().getEStructuralFeature(M_POLYGON);
if (null != mPolygonFeature) {
final Object mPolygonValue = element.eGet(mPolygonFeature);
if (mPolygonValue instanceof List<?>) {
return (List<String>) mPolygonValue;
}
}
final EStructuralFeature mPositionlygonFeature = element.eClass().getEStructuralFeature("m_position");
if (null != mPolygonFeature) {
final Object mPolygonValue = element.eGet(mPolygonFeature);
if (mPolygonValue instanceof List<?>) {
return (List<String>) mPolygonValue;
}
}
return null;
}
@Operation(kind = Kind.HELPER)
public int getRectangleWidth(final GraphElementsType element) {
RpyShape shape = RpyShapeOperations.createRpyShape(element);
return shape.getWidth();
}
@Operation(kind = Kind.HELPER)
public int getRectangleHeight(final GraphElementsType element) {
RpyShape shape = RpyShapeOperations.createRpyShape(element);
return shape.getHeight();
}
@Operation(kind = Kind.HELPER)
public int getX(final GraphElementsType element) {
RpyShape shape = RpyShapeOperations.createRpyShape(element);
return shape.getParentRelativePosition().getIntX();
}
@Operation(kind = Kind.HELPER)
public int getY(final GraphElementsType element) {
RpyShape shape = RpyShapeOperations.createRpyShape(element);
return shape.getParentRelativePosition().getIntY();
}
// TODO : move me into an upper plugin
/**
*
* @param aString
* a string
* @return the parsed result of the string or {@link Integer#MAX_VALUE} if a problem occurred
*/
protected final int stringToInteger(final String aString) {
int result = Integer.MAX_VALUE;
if (aString.contains(".")) { //$NON-NLS-1$
result = Float.valueOf(Float.parseFloat(aString)).intValue();
} else {
result = Integer.parseInt(aString);
}
return result;
}
}