blob: 0511d1eafa7be1e1a498b89a357c8684d317735e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2017 THALES GLOBAL SERVICES.
* 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:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.tests.swtbot;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.EditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.AbstractBorderedShapeEditPart;
import org.eclipse.gmf.runtime.draw2d.ui.geometry.LineSeg;
import org.eclipse.gmf.runtime.notation.Bendpoints;
import org.eclipse.gmf.runtime.notation.Edge;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.runtime.notation.RelativeBendpoints;
import org.eclipse.sirius.diagram.DDiagram;
import org.eclipse.sirius.diagram.DDiagramElement;
import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramBorderNodeEditPart;
import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramEdgeEditPart;
import org.eclipse.sirius.diagram.ui.tools.api.graphical.edit.styles.IBorderItemOffsets;
import org.eclipse.sirius.tests.swtbot.support.api.business.UIDiagramRepresentation.ZoomLevel;
import org.eclipse.sirius.tests.swtbot.support.api.business.UILocalSession;
import org.eclipse.sirius.tests.swtbot.support.api.business.UIResource;
import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotSiriusDiagramEditor;
import org.eclipse.sirius.ui.business.api.preferences.SiriusUIPreferencesKeys;
import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditPart;
/**
* @author smonnier
*/
public class ArrangeAllLinkedBorderedNodesLayoutStabilityTest extends AbstractArrangeAllTest
implements PositionConstants {
/**
* A safety margin because of the method used to compute the port location
* (sometimes, near the corner for example or if the edge is flat, the
* location can be better).
*/
private static final int SAFETY_MARGIN = 5;
private static final String REPRESENTATION_NAME_UC1 = "TC1957";
private static final String REPRESENTATION_NAME_UC2 = "TC1957_withoutLabel";
private static final String REPRESENTATION_NAME_UC3 = "TC1957_Container";
private static final String REPRESENTATION_NAME_UC4 = "TC1957_Container_LeftRight";
private static final String REPRESENTATION_NAME_UC5 = "testReconnect";
private static final String REPRESENTATION_INSTANCE_NAME_UC1 = "UseCase1";
private static final String REPRESENTATION_INSTANCE_NAME_UC2 = "UseCase2";
private static final String REPRESENTATION_INSTANCE_NAME_UC3 = "UseCase3";
private static final String REPRESENTATION_INSTANCE_NAME_UC4 = "UseCase4";
private static final String REPRESENTATION_INSTANCE_NAME_UC5_1 = "UseCase5-1";
private static final String REPRESENTATION_INSTANCE_NAME_UC5_2 = "UseCase5-2";
private static final String REPRESENTATION_INSTANCE_NAME_UC5_3 = "UseCase5-3";
private static final String REPRESENTATION_INSTANCE_NAME_UC5_4 = "UseCase5-4";
private static final String REPRESENTATION_INSTANCE_NAME_UC5_5 = "UseCase5-5";
private static final String REPRESENTATION_INSTANCE_NAME_UC5_6 = "UseCase5-6";
private static final String REPRESENTATION_INSTANCE_NAME_UC5_7 = "UseCase5-7";
private static final String REPRESENTATION_INSTANCE_NAME_UC5_8 = "UseCase5-8";
private static final String REPRESENTATION_INSTANCE_NAME_UC6 = "UseCase6";
private static final String REPRESENTATION_INSTANCE_NAME_UC7 = "new testReconnect";
private static final String REPRESENTATION_INSTANCE_NAME_UC8 = "simpleCase";
private static final String REPRESENTATION_INSTANCE_NAME_UC9 = "simpleCase2";
private static final String REPRESENTATION_INSTANCE_NAME_UC10 = "complexeCase";
private static final String MODEL = "tc1957.ecore";
private static final String MODEL2 = "testReconnect.ecore";
private static final String SESSION_FILE = "tc1957.aird";
private static final String VSM_FILE = "tc1957.odesign";
private static final String DATA_UNIT_DIR = "data/unit/layout/borderedNodes/";
private static final String FILE_DIR = "/";
private UIResource sessionAirdResource;
private UILocalSession localSession;
/**
* True if SnapToGrid is activated on editor, false otherwise.
*/
protected boolean snapToGrid;
/**
* Step used for the grid spacing.
*/
protected static final int GRID_STEP = 20;
@Override
protected void onSetUpBeforeClosingWelcomePage() throws Exception {
// Disable refresh on opening
changeSiriusUIPreference(SiriusUIPreferencesKeys.PREF_REFRESH_ON_REPRESENTATION_OPENING.name(), false);
copyFileToTestProject(Activator.PLUGIN_ID, DATA_UNIT_DIR, MODEL, MODEL2, SESSION_FILE, VSM_FILE);
}
private void arrangeLinkedBorderedNodes() {
if (snapToGrid) {
editor.setSnapToGrid(true, GRID_STEP, 2);
}
editor.clickContextMenu("Linked Border Nodes");
}
private void arrangeAllMenu() {
if (snapToGrid) {
editor.setSnapToGrid(true, GRID_STEP, 2);
}
editor.clickContextMenu("Arrange All");
}
@Override
protected void onSetUpAfterOpeningDesignerPerspective() throws Exception {
sessionAirdResource = new UIResource(designerProject, FILE_DIR, SESSION_FILE);
localSession = designerPerspective.openSessionFromFile(sessionAirdResource, true);
}
/**
* The layout with label (usecase1) is problematic because the label can
* take the place of the port.
*
* @throws Exception
* Test error.
*/
public void testArrangeLinkedBorderNodesCase1() throws Exception {
editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(),
REPRESENTATION_NAME_UC1, REPRESENTATION_INSTANCE_NAME_UC1, DDiagram.class, true, true);
// activate the "Arrange Linked Border Nodes" action
arrangeAllMenu();
// Validate the positions of the bordered nodes.
// We don't check the edges crossing because the label on the border
// nodes can cause crossing (indeed a label can take the place of a
// border node).
validatePositions(false, false);
}
/**
* Test method.
*
* @throws Exception
* Test error.
*/
public void testArrangeLinkedBorderNodesCase2() throws Exception {
editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(),
REPRESENTATION_NAME_UC2, REPRESENTATION_INSTANCE_NAME_UC2, DDiagram.class, true, true);
// activate the "Arrange Linked Border Nodes" action
arrangeAllMenu();
// Validate the positions of the border nodes.
validatePositions(false);
}
/**
* Test method.
*
* @throws Exception
* Test error.
*/
public void testArrangeLinkedBorderNodesCase3() throws Exception {
editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(),
REPRESENTATION_NAME_UC3, REPRESENTATION_INSTANCE_NAME_UC3, DDiagram.class, true, true);
// activate the "Arrange Linked Border Nodes" action
arrangeAllMenu();
// Validate the positions of the border nodes.
validatePositions(true);
}
/**
* Test method. This test check a specific use case an vertical container
* became an horizontal container so the size after arrange is needed (and
* it's not often the case). <BR>
* <B>Currently, this test failed</B> : In this case, the calculation is OK
* (or almost) but during the creation of the command the DBorderItemLocator
* compute the real location with the parent figure (which has not been
* resized). It is resized later with a refreshVisuals after the execution
* of all commands.
* TODO : Correct the problem (if possible) and reactivate this test.
*
* @throws Exception
* Test error.
*/
public void failedTestArrangeLinkedBorderNodesCase4() throws Exception {
editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(),
REPRESENTATION_NAME_UC4, REPRESENTATION_INSTANCE_NAME_UC4, DDiagram.class, true, true);
// activate the "Arrange Linked Border Nodes" action
arrangeAllMenu();
// Validate the positions of the border nodes.
validatePositions(true);
}
/**
* Test method.
*
* @throws Exception
* Test error.
*/
public void testArrangeLinkedBorderNodesCase5_1() throws Exception {
editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(),
REPRESENTATION_NAME_UC2, REPRESENTATION_INSTANCE_NAME_UC5_1, DDiagram.class, true, true);
// activate the "Arrange Linked Border Nodes" action
arrangeLinkedBorderedNodes();
// Validate the positions of the border nodes.
validatePositionsOfUseCase5();
}
/**
* Test method.
*
* @throws Exception
* Test error.
*/
public void testArrangeLinkedBorderNodesCase5_2() throws Exception {
editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(),
REPRESENTATION_NAME_UC2, REPRESENTATION_INSTANCE_NAME_UC5_2, DDiagram.class, true, true);
// activate the "Arrange Linked Border Nodes" action
arrangeLinkedBorderedNodes();
// Validate the positions of the border nodes.
validatePositionsOfUseCase5();
}
/**
* Test method.
*
* @throws Exception
* Test error.
*/
public void testArrangeLinkedBorderNodesCase5_3() throws Exception {
editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(),
REPRESENTATION_NAME_UC2, REPRESENTATION_INSTANCE_NAME_UC5_3, DDiagram.class, true, true);
// activate the "Arrange Linked Border Nodes" action
arrangeLinkedBorderedNodes();
// Validate the positions of the border nodes.
validatePositionsOfUseCase5();
}
/**
* Test method.
*
* @throws Exception
* Test error.
*/
public void testArrangeLinkedBorderNodesCase5_4() throws Exception {
editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(),
REPRESENTATION_NAME_UC2, REPRESENTATION_INSTANCE_NAME_UC5_4, DDiagram.class, true, true);
// activate the "Arrange Linked Border Nodes" action
arrangeLinkedBorderedNodes();
// Validate the positions of the border nodes.
validatePositionsOfUseCase5();
}
/**
* Test method.
*
* @throws Exception
* Test error.
*/
public void testArrangeLinkedBorderNodesCase5_5() throws Exception {
editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(),
REPRESENTATION_NAME_UC2, REPRESENTATION_INSTANCE_NAME_UC5_5, DDiagram.class, true, true);
arrangeLinkedBorderedNodes();
// Validate the positions of the bordered nodes.
validatePositionsOfUseCase5();
}
/**
* Test method.
*
* @throws Exception
* Test error.
*/
public void testArrangeLinkedBorderNodesCase5_6() throws Exception {
editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(),
REPRESENTATION_NAME_UC2, REPRESENTATION_INSTANCE_NAME_UC5_6, DDiagram.class, true, true);
// activate the "Arrange Linked Border Nodes" action
arrangeLinkedBorderedNodes();
// Validate the positions of the border nodes.
validatePositionsOfUseCase5();
}
/**
* Test method.
*
* @throws Exception
* Test error.
*/
public void testArrangeLinkedBorderNodesCase5_7() throws Exception {
editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(),
REPRESENTATION_NAME_UC2, REPRESENTATION_INSTANCE_NAME_UC5_7, DDiagram.class, true, true);
// activate the "Arrange Linked Border Nodes" action
arrangeLinkedBorderedNodes();
// Validate the positions of the border nodes.
validatePositionsOfUseCase5();
}
/**
* Test method.
*
* @throws Exception
* Test error.
*/
public void testArrangeLinkedBorderNodesCase5_8() throws Exception {
editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(),
REPRESENTATION_NAME_UC2, REPRESENTATION_INSTANCE_NAME_UC5_8, DDiagram.class, true, true);
// activate the "Arrange Linked Border Nodes" action
arrangeLinkedBorderedNodes();
// Validate the positions of the border nodes.
validatePositionsOfUseCase5();
}
/**
* Test method.
*
* @throws Exception
* Test error.
*/
public void testArrangeLinkedBorderNodesCase6() throws Exception {
editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(),
REPRESENTATION_NAME_UC3, REPRESENTATION_INSTANCE_NAME_UC6, DDiagram.class, true, true);
// activate the "Arrange Linked Border Nodes" action
arrangeLinkedBorderedNodes();
// Validate the positions of the border nodes.
validatePositions(true);
}
/**
* Test method.
*
* @throws Exception
* Test error.
*/
public void testArrangeLinkedBorderNodesCase7() throws Exception {
editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(),
REPRESENTATION_NAME_UC5, REPRESENTATION_INSTANCE_NAME_UC7, DDiagram.class, true, true);
// activate the "Arrange Linked Border Nodes" action
arrangeLinkedBorderedNodes();
// Validate the positions of the border nodes.
validatePositionOfPortOnContainer("package2", "eClass4");
validatePositionOfPortOnContainer("package1", "eClass2");
validatePositionOfPortOnContainer("Package1", "eClass2");
validatePositionOfPortOnContainer("Package1", "eClass4");
validatePositionOfPortOnContainer("Package2", "eClass4");
validatePositionOfPortOnContainer("Package2", "eClass1");
}
/**
* Test method.
*
* @throws Exception
* Test error.
*/
public void testArrangeLinkedBorderNodesCase7WithZoom() throws Exception {
editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(),
REPRESENTATION_NAME_UC5, REPRESENTATION_INSTANCE_NAME_UC7, DDiagram.class, true, true);
editor.zoom(ZoomLevel.ZOOM_200);
try {
// activate the "Arrange Linked Border Nodes" action
arrangeLinkedBorderedNodes();
// Validate the positions of the border nodes.
validatePositionOfPortOnContainer("package2", "eClass4");
validatePositionOfPortOnContainer("package1", "eClass2");
validatePositionOfPortOnContainer("Package1", "eClass2");
validatePositionOfPortOnContainer("Package1", "eClass4");
validatePositionOfPortOnContainer("Package2", "eClass4");
validatePositionOfPortOnContainer("Package2", "eClass1");
} finally {
editor.zoom(ZoomLevel.ZOOM_100);
}
}
/**
* Test method.
*
* @throws Exception
* Test error.
*/
public void testArrangeLinkedBorderNodesCase8() throws Exception {
editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(),
REPRESENTATION_NAME_UC5, REPRESENTATION_INSTANCE_NAME_UC8, DDiagram.class, true, true);
// activate the "Arrange Linked Border Nodes" action
arrangeLinkedBorderedNodes();
// Validate the positions of the border nodes.
validatePositionOfPortOnContainer("package1", "eClass2");
validatePositionOfPortOnContainer("package2", "eClass4");
}
/**
* Test method.
*
* @throws Exception
* Test error.
*/
public void testArrangeLinkedBorderNodesCase8WithZoom() throws Exception {
editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(),
REPRESENTATION_NAME_UC5, REPRESENTATION_INSTANCE_NAME_UC8, DDiagram.class, true, true);
editor.zoom(ZoomLevel.ZOOM_200);
try {
// activate the "Arrange Linked Border Nodes" action
arrangeLinkedBorderedNodes();
// Validate the positions of the border nodes.
validatePositionOfPortOnContainer("package1", "eClass2");
validatePositionOfPortOnContainer("package2", "eClass4");
} finally {
editor.zoom(ZoomLevel.ZOOM_100);
}
}
/**
* Test method.
*
* @throws Exception
* Test error.
*/
public void testArrangeLinkedBorderNodesCase9() throws Exception {
editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(),
REPRESENTATION_NAME_UC5, REPRESENTATION_INSTANCE_NAME_UC9, DDiagram.class, true, true);
// activate the "Arrange Linked Border Nodes" action
arrangeLinkedBorderedNodes();
// Validate the positions of the border nodes.
validatePositionOfPortOnContainer("package1", "eClass2");
validatePositionOfPortOnContainer("package2", "eClass4");
}
/**
* Test method.
*
* @throws Exception
* Test error.
*/
public void testArrangeLinkedBorderNodesCase9WithZoom() throws Exception {
editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(),
REPRESENTATION_NAME_UC5, REPRESENTATION_INSTANCE_NAME_UC9, DDiagram.class, true, true);
editor.zoom(ZoomLevel.ZOOM_200);
try {
// activate the "Arrange Linked Border Nodes" action
arrangeLinkedBorderedNodes();
// Validate the positions of the border nodes.
validatePositionOfPortOnContainer("package1", "eClass2");
validatePositionOfPortOnContainer("package2", "eClass4");
} finally {
editor.zoom(ZoomLevel.ZOOM_100);
}
}
/**
* Test method.
*
* @throws Exception
* Test error.
*/
public void testArrangeLinkedBorderNodesCase10() throws Exception {
editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(),
REPRESENTATION_NAME_UC5, REPRESENTATION_INSTANCE_NAME_UC10, DDiagram.class, true, true);
// activate the "Arrange Linked Border Nodes" action
arrangeLinkedBorderedNodes();
// Validate the positions of the border nodes.
validatePositionOfPortOnContainer("Package1", "eClass2");
validatePositionOfPortOnContainer("Package1", "eClass4");
validatePositionOfPortOnContainer("Package2", "eClass1");
validatePositionOfPortOnContainer("Package2", "eClass4");
}
/**
* Test method.
*
* @throws Exception
* Test error.
*/
public void testArrangeLinkedBorderNodesCase10WithZoom() throws Exception {
editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(),
REPRESENTATION_NAME_UC5, REPRESENTATION_INSTANCE_NAME_UC10, DDiagram.class, true, true);
editor.zoom(ZoomLevel.ZOOM_200);
try {
// activate the "Arrange Linked Border Nodes" action
arrangeLinkedBorderedNodes();
// Validate the positions of the border nodes.
validatePositionOfPortOnContainer("Package1", "eClass2");
validatePositionOfPortOnContainer("Package1", "eClass4");
validatePositionOfPortOnContainer("Package2", "eClass1");
validatePositionOfPortOnContainer("Package2", "eClass4");
} finally {
editor.zoom(ZoomLevel.ZOOM_100);
}
}
/**
* Validate the positions of all bordered nodes.
*
* @param isDiagramWithRecursivePackage
* true if the diagram to validate is with recursive package
* @param validateEdgeCrossing
* true if this method must check the edge crossing, false
* otherwise
*/
private void validatePositions(boolean isDiagramWithRecursivePackage, boolean validateEdgeCrossing) {
validatePositionOfPortOnContainer("P1", "C11");
validatePositionOfPortOnContainer("P1", "C12");
validatePositionOfPortOnContainer("p2", "C21");
validatePositionOfPortOnContainer("p2", "C22");
validatePositionOfPortOnContainer("p3", "C31");
validatePositionOfPortOnContainer("p3", "C32");
validatePositionOfPortOnContainer("p3", "C33");
validatePositionOfPortOnContainer("p4", "C41");
validatePositionOfPortOnContainer("p4", "C42");
validatePositionOfPortOnContainer("p4", "C43");
validatePositionOfPortOnContainer("p5", "C51");
validatePositionOfPortOnContainer("p5", "C52");
validatePositionOfPortOnContainer("p5", "C53");
validatePositionOfPortOnContainer("p5", "C54");
validatePositionOfPortOnContainer("p6", "C61");
validatePositionOfPortOnContainer("p6", "C62");
validatePositionOfPortOnContainer("p6", "C63");
validatePositionOfPortOnContainer("p6", "C64");
validatePositionOfPortOnContainer("p7", "C71");
validatePositionOfPortOnContainer("p7", "C72");
validatePositionOfPortOnContainer("p7", "C73");
validatePositionOfPortOnContainer("p10", "C101");
if (isDiagramWithRecursivePackage) {
validatePositionOfPortOnContainer("p8", "C81");
validatePositionOfPortOnContainer("p9", "C91");
validatePositionOfPortOnContainer("p9", "C92");
validatePositionOfPortOnContainer("p9", "C93");
validatePositionOfPortOnContainer("p12", "C121");
validatePositionOfPortOnContainer("p11", "C111");
}
if (validateEdgeCrossing) {
validateCrossEdges(isDiagramWithRecursivePackage);
}
}
/**
* Validate the positions of all bordered nodes.
*
* @param isDiagramWithrecursivePackage
* true if the diagram to validate is with recursive package
*/
private void validatePositions(final boolean isDiagramWithRecursivePackage) {
validatePositions(isDiagramWithRecursivePackage, true);
}
/**
* @param isDiagramWithRecursivePackage
*/
private void validateCrossEdges(boolean isDiagramWithRecursivePackage) {
String message = "Some intersections exist after layout";
assertNull(message, getLineSeg("P1", "C11", "p2", "C21").intersect(getLineSeg("P1", "C12", "p2", "C22"), 0));
assertNull(message, getLineSeg("p3", "C31", "p4", "C41").intersect(getLineSeg("p3", "C32", "p4", "C42"), 0));
assertNull(message, getLineSeg("p3", "C31", "p4", "C41").intersect(getLineSeg("p3", "C33", "p4", "C43"), 0));
assertNull(message, getLineSeg("p3", "C32", "p4", "C42").intersect(getLineSeg("p3", "C33", "p4", "C43"), 0));
assertNull(message, getLineSeg("p5", "C51", "p6", "C61").intersect(getLineSeg("p5", "C52", "p6", "C62"), 0));
assertNull(message, getLineSeg("p5", "C51", "p6", "C61").intersect(getLineSeg("p5", "C53", "p6", "C64"), 0));
assertNull(message, getLineSeg("p5", "C51", "p6", "C61").intersect(getLineSeg("p5", "C54", "p6", "C63"), 0));
assertNull(message, getLineSeg("p5", "C52", "p6", "C62").intersect(getLineSeg("p5", "C53", "p6", "C64"), 0));
assertNull(message, getLineSeg("p5", "C52", "p6", "C62").intersect(getLineSeg("p5", "C54", "p6", "C63"), 0));
assertNull(message, getLineSeg("p5", "C53", "p6", "C64").intersect(getLineSeg("p5", "C54", "p6", "C63"), 0));
if (isDiagramWithRecursivePackage) {
assertNull(message,
getLineSeg("p7", "C71", "p9", "C92").intersect(getLineSeg("p7", "C72", "p9", "C91"), 0));
assertNull(message,
getLineSeg("p7", "C71", "p9", "C92").intersect(getLineSeg("p7", "C73", "p10", "C101"), 0));
assertNull(message,
getLineSeg("p7", "C72", "p9", "C91").intersect(getLineSeg("p7", "C73", "p10", "C101"), 0));
}
}
/**
* Validate the positions of all bordered nodes.
*/
private void validatePositionsOfUseCase5() {
validatePositionOfPortOnContainer("p5", "C51");
validatePositionOfPortOnContainer("p5", "C52");
validatePositionOfPortOnContainer("p5", "C53");
validatePositionOfPortOnContainer("p5", "C54");
validatePositionOfPortOnContainer("p6", "C61");
validatePositionOfPortOnContainer("p6", "C62");
validatePositionOfPortOnContainer("p6", "C63");
validatePositionOfPortOnContainer("p6", "C64");
String message = "Some intersections exist after layout";
assertNull(message, getLineSeg("p5", "C51", "p6", "C61").intersect(getLineSeg("p5", "C52", "p6", "C62"), 0));
assertNull(message, getLineSeg("p5", "C51", "p6", "C61").intersect(getLineSeg("p5", "C53", "p6", "C64"), 0));
assertNull(message, getLineSeg("p5", "C51", "p6", "C61").intersect(getLineSeg("p5", "C54", "p6", "C63"), 0));
assertNull(message, getLineSeg("p5", "C52", "p6", "C62").intersect(getLineSeg("p5", "C53", "p6", "C64"), 0));
assertNull(message, getLineSeg("p5", "C52", "p6", "C62").intersect(getLineSeg("p5", "C54", "p6", "C63"), 0));
assertNull(message, getLineSeg("p5", "C53", "p6", "C64").intersect(getLineSeg("p5", "C54", "p6", "C63"), 0));
}
/**
* @param sourceContainerName
* @param sourcePortName
* @param targetContainerName
* @param targetPortName
* @return
*/
private LineSeg getLineSeg(String sourceContainerName, String sourcePortName, String targetContainerName,
String targetPortName) {
SWTBotGefEditPart swtbotSourceContainerEditPart = editor.getEditPart(sourceContainerName);
assertNotNull("No container edit part found with this name", swtbotSourceContainerEditPart);
EditPart sourceContainerSquareEP = swtbotSourceContainerEditPart.part();
assertTrue("The parent edit part of the container label is not a AbstractBorderedShapeEditPart",
sourceContainerSquareEP.getParent() instanceof AbstractBorderedShapeEditPart);
final AbstractBorderedShapeEditPart sourceContainerEP = (AbstractBorderedShapeEditPart) sourceContainerSquareEP
.getParent();
final AbstractDiagramBorderNodeEditPart sourcePortEP = findPortInContainer(sourceContainerEP, sourcePortName);
assertNotNull("No port edit part found with this name", sourcePortEP);
SWTBotGefEditPart swtbotTargetContainerEditPart = editor.getEditPart(targetContainerName);
assertNotNull("No container edit part found with this name", swtbotTargetContainerEditPart);
EditPart targetContainerSquareEP = swtbotTargetContainerEditPart.part();
assertTrue("The parent edit part of the container label is not a AbstractBorderedShapeEditPart",
targetContainerSquareEP.getParent() instanceof AbstractBorderedShapeEditPart);
final AbstractBorderedShapeEditPart targetContainerEP = (AbstractBorderedShapeEditPart) targetContainerSquareEP
.getParent();
final AbstractDiagramBorderNodeEditPart targetPortEP = findPortInContainer(targetContainerEP, targetPortName);
assertNotNull("No port edit part found with this name", targetPortEP);
return new LineSeg(editor.getAbsoluteCenter(sourcePortEP), editor.getAbsoluteCenter(targetPortEP));
}
/**
* Check that the port is arranged correctly.
*
* @param containerName
* The container name
* @param portName
* The port name
*/
private void validatePositionOfPortOnContainer(String containerName, String portName) {
validatePositionOfPortOnContainer(containerName, portName, false);
}
/**
* Check that the port is arranged correctly.
*
* @param containerName
* The container name
* @param portName
* The port name
* @param pinBorderedNodes
* true if the port must be pin during the validation of it
*/
protected void validatePositionOfPortOnContainer(String containerName, String portName, boolean pinBorderedNodes) { // ,
// int
// position){
SWTBotGefEditPart swtbotContainerEditPart = editor.getEditPart(containerName);
assertNotNull("No container edit part found with this name", swtbotContainerEditPart);
EditPart containerSquareEP = swtbotContainerEditPart.part();
assertTrue("The parent edit part of the container label is not a AbstractBorderedShapeEditPart",
containerSquareEP.getParent() instanceof AbstractBorderedShapeEditPart);
final AbstractBorderedShapeEditPart containerEP = (AbstractBorderedShapeEditPart) containerSquareEP.getParent();
final AbstractDiagramBorderNodeEditPart portEP = findPortInContainer(containerEP, portName);
assertNotNull("No port edit part found with this name", portEP);
if (pinBorderedNodes) {
pinDiagramElement((DDiagramElement) ((Node) portEP.getModel()).getElement());
}
if (!snapToGrid) {
// This test is not done when snapToGrid is enabled as the snap can
// break the "arrange all linked border nodes" rules.
boolean edgeFromPortCrossParentContainer = validateEdgeFromPortCrossParentContainer(containerEP, portEP);
assertFalse("The port " + portName + " has an edge that cross the parent container " + containerName,
edgeFromPortCrossParentContainer);
}
boolean validateEdgeFromPortHaveBendpointsReset = validateEdgeFromPortHaveBendpointsReset(containerEP, portEP);
assertTrue("The port " + portName + " has an edge that don't have its bendpoints reset " + containerName,
validateEdgeFromPortHaveBendpointsReset);
// boolean validatePositionOfPortOnContainer =
// validatePositionOfPortOnContainer(containerEP, portEP, position);
//
// assertTrue("The port "+portName+" is not in the expected position
// relatively to the container "+containerName,
// validatePositionOfPortOnContainer);
}
/**
* Check that the port is on the expected side.
*
* @param containerName
* The container name
* @param portName
* The port name
* @param position
* The expected side.
* @param pinPorts
* true is the port must be pin during the validation
*/
private void validatePositionOfPortOnContainer(String containerName, String portName, int position,
boolean pinPorts) {
SWTBotGefEditPart swtbotContainerEditPart = editor.getEditPart(containerName);
assertNotNull("No container edit part found with this name", swtbotContainerEditPart);
EditPart containerSquareEP = swtbotContainerEditPart.part();
assertTrue("The parent edit part of the container label is not a AbstractBorderedShapeEditPart",
containerSquareEP.getParent() instanceof AbstractBorderedShapeEditPart);
final AbstractBorderedShapeEditPart containerEP = (AbstractBorderedShapeEditPart) containerSquareEP.getParent();
final AbstractDiagramBorderNodeEditPart portEP = findPortInContainer(containerEP, portName);
assertNotNull("No port edit part found with this name", portEP);
if (pinPorts) {
pinDiagramElement((DDiagramElement) ((Node) portEP.getModel()).getElement());
}
boolean validatePositionOfPortOnContainer = validatePositionOfPortOnContainer(containerEP, portEP, position);
assertTrue("The port " + portName + " is not in the expected position relatively to the container "
+ containerName, validatePositionOfPortOnContainer);
}
private boolean validateEdgeFromPortCrossParentContainer(final AbstractBorderedShapeEditPart containerEP,
final AbstractDiagramBorderNodeEditPart portEP) {
Rectangle containerBounds = containerEP.getFigure().getBounds().getCopy();
containerEP.getFigure().translateToAbsolute(containerBounds);
List<AbstractDiagramEdgeEditPart> edgesEP = listEdgesConnectedToPort(portEP);
if (edgesEP.size() == 1) {
for (AbstractDiagramEdgeEditPart edgeEP : edgesEP) {
int north = findNorth(edgeEP);
int south = findSouth(edgeEP);
int west = findWest(edgeEP);
int east = findEast(edgeEP);
Rectangle edgeBounds = new Rectangle(west + SAFETY_MARGIN, north + SAFETY_MARGIN,
east - west - (SAFETY_MARGIN * 2), south - north - (SAFETY_MARGIN * 2));
return edgeBounds.intersects(containerBounds);
}
}
return false;
}
private boolean validateEdgeFromPortHaveBendpointsReset(final AbstractBorderedShapeEditPart containerEP,
final AbstractDiagramBorderNodeEditPart portEP) {
List<AbstractDiagramEdgeEditPart> edgesEP = listEdgesConnectedToPort(portEP);
if (!edgesEP.isEmpty()) {
for (AbstractDiagramEdgeEditPart edgeEP : edgesEP) {
Bendpoints bendpoints = ((Edge) edgeEP.getNotationView()).getBendpoints();
if (bendpoints instanceof RelativeBendpoints
&& ((RelativeBendpoints) bendpoints).getPoints().size() != 2) {
return false;
}
}
}
return true;
}
private int findNorth(final AbstractDiagramEdgeEditPart edgeEP) {
int north = Integer.MAX_VALUE;
PointList points = edgeEP.getPolylineConnectionFigure().getPoints().getCopy();
for (int i = 0; i < points.size(); i++) {
Point point = points.getPoint(i);
if (point.y < north)
north = point.y;
}
return north;
}
private int findSouth(final AbstractDiagramEdgeEditPart edgeEP) {
int south = Integer.MIN_VALUE;
PointList points = edgeEP.getPolylineConnectionFigure().getPoints().getCopy();
for (int i = 0; i < points.size(); i++) {
Point point = points.getPoint(i);
if (point.y > south)
south = point.y;
}
return south;
}
private int findWest(final AbstractDiagramEdgeEditPart edgeEP) {
int west = Integer.MAX_VALUE;
PointList points = edgeEP.getPolylineConnectionFigure().getPoints().getCopy();
for (int i = 0; i < points.size(); i++) {
Point point = points.getPoint(i);
if (point.x < west)
west = point.x;
}
return west;
}
private int findEast(final AbstractDiagramEdgeEditPart edgeEP) {
int west = Integer.MIN_VALUE;
PointList points = edgeEP.getPolylineConnectionFigure().getPoints().getCopy();
for (int i = 0; i < points.size(); i++) {
Point point = points.getPoint(i);
if (point.x > west)
west = point.x;
}
return west;
}
protected List<AbstractDiagramEdgeEditPart> listEdgesConnectedToPort(final AbstractDiagramBorderNodeEditPart portEP) {
ArrayList<AbstractDiagramEdgeEditPart> linkedPorts = new ArrayList<AbstractDiagramEdgeEditPart>();
Iterator<?> targetIterator = portEP.getTargetConnections().iterator();
while (targetIterator.hasNext()) {
Object object = targetIterator.next();
if (object instanceof AbstractDiagramEdgeEditPart) {
AbstractDiagramEdgeEditPart edgeEP = (AbstractDiagramEdgeEditPart) object;
linkedPorts.add(edgeEP);
}
}
Iterator<?> sourceIterator = portEP.getSourceConnections().iterator();
while (sourceIterator.hasNext()) {
Object object = sourceIterator.next();
if (object instanceof AbstractDiagramEdgeEditPart) {
AbstractDiagramEdgeEditPart edgeEP = (AbstractDiagramEdgeEditPart) object;
linkedPorts.add(edgeEP);
}
}
return linkedPorts;
}
private boolean validatePositionOfPortOnContainer(AbstractBorderedShapeEditPart containerEP,
AbstractDiagramBorderNodeEditPart portEP, int position) {
Rectangle boundsPort = portEP.getFigure().getBounds();
Rectangle boundsContainer = containerEP.getFigure().getBounds();
switch (position) {
case NORTH:
return Math.abs(boundsContainer.y - boundsPort.y) < IBorderItemOffsets.DEFAULT_OFFSET.height;
case EAST:
return Math.abs(boundsContainer.x + boundsContainer.width - boundsPort.x
- boundsPort.width) < IBorderItemOffsets.DEFAULT_OFFSET.width;
case SOUTH:
return Math.abs(boundsContainer.y + boundsContainer.height - boundsPort.y
- boundsPort.height) < IBorderItemOffsets.DEFAULT_OFFSET.height;
case WEST:
return Math.abs(boundsContainer.x - boundsPort.x) < IBorderItemOffsets.DEFAULT_OFFSET.width;
default:
fail("The position should be one among North/East/South/West.");
break;
}
return false;
}
/**
* Extract port from a container with a given name.
*
* @param containerEP
* container which contains the port
* @param portName
* name of the port to find
* @return port from a container with a given name.
*/
protected AbstractDiagramBorderNodeEditPart findPortInContainer(AbstractBorderedShapeEditPart containerEP,
String portName) {
Iterator<?> iterator = containerEP.getChildren().iterator();
while (iterator.hasNext()) {
Object object = iterator.next();
if (object instanceof AbstractDiagramBorderNodeEditPart) {
AbstractDiagramBorderNodeEditPart portEP = (AbstractDiagramBorderNodeEditPart) object;
Object portModel = portEP.getModel();
if (portModel instanceof Node) {
Node portNode = (Node) portModel;
EObject portElement = portNode.getElement();
if (portElement instanceof DDiagramElement) {
DDiagramElement portDDiagramElement = (DDiagramElement) portElement;
Iterator<EObject> semanticElementsIterator = portDDiagramElement.getSemanticElements()
.iterator();
while (semanticElementsIterator.hasNext()) {
EObject eObject = semanticElementsIterator.next();
if (eObject instanceof ENamedElement) {
ENamedElement ref = (ENamedElement) eObject;
if (ref.getName().equals(portName)) {
return portEP;
}
}
}
}
}
}
}
return null;
}
}