/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.gui.workflow; import java.util.ArrayList; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import de.rcenvironment.core.component.workflow.model.api.Connection; import de.rcenvironment.core.component.workflow.model.api.Location; import de.rcenvironment.core.component.workflow.model.api.WorkflowDescription; import de.rcenvironment.core.component.workflow.model.api.WorkflowNode; import de.rcenvironment.core.gui.workflow.parts.ConnectionWrapper; /** * Utility class with useful methods when working with connections, connection wrappers etc. * * @author Oliver Seebach * */ public final class ConnectionUtils { private static final Log LOGGER = LogFactory.getLog(ConnectionUtils.class); private ConnectionUtils() { // prevent instantiation } /** * Finds connections between the two given nodes in the given workflow description. Considers both directions. * * @param sourceNode The first node to be considered. * @param targetNode The second node to be considered. * @param workflowDescription The workflow description to be searched in. * @return The connections between the two given nodes. */ public static List<Connection> getConnectionsBetweenNodes(WorkflowNode sourceNode, WorkflowNode targetNode, WorkflowDescription workflowDescription) { List<Connection> connectionsBetweenNodes = new ArrayList<>(); if (sourceNode != null && targetNode != null && workflowDescription != null) { for (Connection connection : workflowDescription.getConnections()) { if ((connection.getSourceNode().getIdentifier().equals(sourceNode.getIdentifier()) && connection.getTargetNode().getIdentifier().equals(targetNode.getIdentifier())) || (connection.getSourceNode().getIdentifier().equals(targetNode.getIdentifier()) && connection.getTargetNode().getIdentifier().equals(sourceNode.getIdentifier()))) { connectionsBetweenNodes.add(connection); } } } return connectionsBetweenNodes; } /** * Finds a list of bendpoints for a connection between two given workflow nodes in the given workflow description. As the bendpoints are * equal for all connections between the same nodes the result is returned as soon as the first connection matches the given source and * target nodes. * * @param source The source node. * @param target The target node. * @param workflowDescription The workflow description. * @return The list of */ public static List<Location> findAlreadyExistentBendpointsBySourceAndTarget(WorkflowNode source, WorkflowNode target, WorkflowDescription workflowDescription) { List<Location> alreadyExistentBendpoints = new ArrayList<>(); for (Connection connection : workflowDescription.getConnections()) { if ((connection.getSourceNode().getIdentifier().equals(source.getIdentifier()) && connection.getTargetNode().getIdentifier().equals(target.getIdentifier()))) { alreadyExistentBendpoints = connection.getBendpoints(); break; } else if (connection.getSourceNode().getIdentifier().equals(target.getIdentifier()) && connection.getTargetNode().getIdentifier().equals(source.getIdentifier())) { // invert order for (Location l : connection.getBendpoints()) { alreadyExistentBendpoints.add(0, l); } break; } } return alreadyExistentBendpoints; } /** * Translates a list of bendpoints by a given offset. * * @param originalBendpoints The original bendpoints. * @param bendpointOffsetX The offset to translate in X direction. * @param bendpointOffsetY The offset to translate in Y direction. * @return The translated list of bendpoints. */ public static List<Location> translateBendpointListByOffset(List<Location> originalBendpoints, int bendpointOffsetX, int bendpointOffsetY) { List<Location> bendpointsWithOffset = new ArrayList<>(); for (Location originalLocation : originalBendpoints) { bendpointsWithOffset.add(new Location(originalLocation.x + bendpointOffsetX, originalLocation.y + bendpointOffsetY)); } return bendpointsWithOffset; } /** * Validates whether all connections in a connectionwrapper have the same amount of bendpoints. * * @param connectionWrapper The connection wrapper to be considered * @param workflowDescription The workflow description to be considered * @param classAndMethod The calling class and method. */ public static void validateConnectionWrapperForEqualBendpointLocations(WorkflowDescription workflowDescription, ConnectionWrapper connectionWrapper, String classAndMethod) { List<Connection> connections = getConnectionsByWrapper(workflowDescription, connectionWrapper); validateConnections(connections, classAndMethod); } /** * Validates whether connections have the same bendpoints. * * @param connections The connections to validate. * @param classAndMethod The calling class and method. */ public static void validateConnections(List<Connection> connections, String classAndMethod) { int numberOfBendpoints = connections.get(0).getBendpoints().size(); for (Connection connection : connections) { if (!checkIfBendpointListsAreEqual(connections.get(0).getBendpoints(), connection.getBendpoints())) { LOGGER.error("Connections' bendpoints are inconsistent! Connection between '" + connection.getSourceNode().getName() + "' and '" + connection.getTargetNode().getName() + "' is affected. It has " + connection.getBendpoints().size() + " bendpoints (" + connection.getBendpoints() + "), but should have " + numberOfBendpoints + " bendpoints (" + connections.get(0).getBendpoints() + "). Caused by " + classAndMethod); break; } } } private static boolean checkIfBendpointListsAreEqual(List<Location> bendpointList, List<Location> bendpointListToCompare){ if (bendpointList.size() != bendpointListToCompare.size()){ return false; } for (int i = 0; i < bendpointList.size(); i++){ if ((bendpointList.get(i).x != bendpointListToCompare.get(i).x && bendpointList.get(i).x != bendpointListToCompare.get(bendpointList.size() - i - 1).x) || (bendpointList.get(i).y != bendpointListToCompare.get(i).y && bendpointList.get(i).y != bendpointListToCompare.get(bendpointList.size() - i - 1).y)){ return false; } } return true; } /** * Return the connections wrapped in a connection wrapper. * * @param connectionWrapper The connection wrapper to be considered * @param workflowDescription The workflow description to be considered * @return The connections in a connection wrapper. */ public static List<Connection> getConnectionsByWrapper(WorkflowDescription workflowDescription, ConnectionWrapper connectionWrapper) { List<Connection> connections = new ArrayList<>(); for (Connection connectionInModel : workflowDescription.getConnections()) { if ((connectionWrapper.getSource().getIdentifier().equals(connectionInModel.getSourceNode().getIdentifier()) && connectionWrapper.getTarget().getIdentifier().equals(connectionInModel.getTargetNode().getIdentifier())) || (connectionWrapper.getTarget().getIdentifier().equals(connectionInModel.getSourceNode().getIdentifier()) && connectionWrapper.getSource().getIdentifier().equals(connectionInModel.getTargetNode().getIdentifier()))) { connections.add(connectionInModel); } } return connections; } }