/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.component.workflow.model.api; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import de.rcenvironment.core.component.model.api.ComponentDescription; import de.rcenvironment.core.component.model.endpoint.api.EndpointDescription; import de.rcenvironment.core.component.model.spi.PropertiesChangeSupport; /** * Connection class for connecting {@link ComponentDescription}s within a {@link WorkflowDescription}. * * @author Roland Gude * @author Heinrich Wendel * @author Oliver Seebach */ public class Connection extends PropertiesChangeSupport implements Serializable, Comparable<Connection> { /** Property that is fired when a bendpoint has been changed. */ public static final String PROPERTY_BENDPOINT = "de.rcenvironment.bendpoint"; private static final long serialVersionUID = 6019856436149503867L; /** The source {@link WorkflowNode}. */ private final WorkflowNode sourceWorkflowNode; /** The output of the source {@link WorkflowNode}. */ private final EndpointDescription outputEndpointDescription; /** The target {@link WorkflowNode}. */ private final WorkflowNode targetWorkflowNode; /** The input of the target {@link WorkflowNode}. */ private final EndpointDescription inputEndpointDescription; private List<Location> bendpoints = new ArrayList<>(); public Connection(WorkflowNode source, EndpointDescription output, WorkflowNode target, EndpointDescription input) { this.sourceWorkflowNode = source; this.outputEndpointDescription = output; this.targetWorkflowNode = target; this.inputEndpointDescription = input; } public Connection(WorkflowNode source, EndpointDescription output, WorkflowNode target, EndpointDescription input, List<Location> bendpoints) { this.sourceWorkflowNode = source; this.outputEndpointDescription = output; this.targetWorkflowNode = target; this.inputEndpointDescription = input; this.bendpoints = new ArrayList<Location>(bendpoints); } public WorkflowNode getSourceNode() { return sourceWorkflowNode; } public EndpointDescription getOutput() { return outputEndpointDescription; } public WorkflowNode getTargetNode() { return targetWorkflowNode; } public EndpointDescription getInput() { return inputEndpointDescription; } @Override public boolean equals(Object o) { boolean equals = false; if (o instanceof Connection) { Connection c = (Connection) o; if (c.getTargetNode().getIdentifier().equals(targetWorkflowNode.getIdentifier()) && c.getSourceNode().getIdentifier().equals(sourceWorkflowNode.getIdentifier()) && inputEndpointDescription.getIdentifier().equals(c.getInput().getIdentifier()) && outputEndpointDescription.getIdentifier().equals(c.getOutput().getIdentifier())) { equals = true; } } return equals; } @Override public int hashCode() { StringBuilder builder = new StringBuilder(); builder.append(targetWorkflowNode.getIdentifier()); builder.append(sourceWorkflowNode.getIdentifier()); builder.append(inputEndpointDescription.getIdentifier()); builder.append(outputEndpointDescription.getIdentifier()); return builder.toString().hashCode(); } /** * Adds a list of bendpoints to a connection. The index of the list passed it used as index of the bendpoints. * * The {@link Location} instances are not modified. TODO remove comment if {@link Location} is immutable. * * @param locations list describing bendpoints */ public void addBendpoints(List<Location> locations){ for (int i = 0; i < locations.size(); i++) { this.bendpoints.add(i, new Location(locations.get(i).x, locations.get(i).y)); } firePropertyChange(PROPERTY_BENDPOINT); } /** * Adds a bendpoint to a connection. * * @param index the index * @param x the x coordinate * @param y the y coordinate * @param inverse flag whether the connection is from source to target or inverse */ public void addBendpoint(int index, int x, int y, boolean inverse){ int indexToUse = new Integer(index); if (inverse) { indexToUse = (bendpoints.size() - indexToUse); } boolean alreadyExistent = false; for (Location location : this.bendpoints){ if (location.x == x && location.y == y){ alreadyExistent = true; } } if (!alreadyExistent){ this.bendpoints.add(indexToUse, new Location(x, y)); firePropertyChange(PROPERTY_BENDPOINT); } } /** * Removes a bendpoint from a connection. * * @param index the index * @param inverse whether connection is inverse wrt its wrapper */ public void removeBendpoint(int index, boolean inverse){ int indexToUse = new Integer(index); if (inverse) { indexToUse = (bendpoints.size() - indexToUse - 1); } if (indexToUse >= 0 && indexToUse < bendpoints.size() && bendpoints.size() > 0){ bendpoints.remove(indexToUse); } firePropertyChange(PROPERTY_BENDPOINT); } /** * Sets a bendpoint at the given index. * * @param index the index * @param x the x coordinate * @param y the y coordinate * @param inverse whether connection is inverse wrt its wrapper */ public void setBendpoint(int index, int x, int y, boolean inverse){ int indexToUse = new Integer(index); if (inverse) { indexToUse = (bendpoints.size() - indexToUse) - 1; } if (indexToUse >= 0 && indexToUse <= bendpoints.size() && bendpoints.size() > 0){ Location location = new Location(x, y); bendpoints.set(indexToUse, location); } firePropertyChange(PROPERTY_BENDPOINT); } /** * Removes a bendpoint from a connection. * * @param index the index */ public void removeBendpoint(int index){ bendpoints.remove(index); firePropertyChange(PROPERTY_BENDPOINT); } /** * Returns a bendpoint from a connection. * * @param index the index * @return the bendpoint */ public Location getBendpoint(int index){ return bendpoints.get(index); } /** * @return list of bendpoints or <code>null</code> if no bendpoints exist (null check needed as member variable 'bendpoints' can be null * until RCE 7) */ public List<Location> getBendpoints() { if (bendpoints != null) { return new ArrayList<Location>(bendpoints); } else { return null; } } /** * Sets the bendpoints for a connection. * * @param bendpoints the bendpoints to be set. */ public void setBendpoints(List<Location> bendpoints) { this.bendpoints = new ArrayList<Location>(bendpoints); firePropertyChange(PROPERTY_BENDPOINT); } /** * Sets a bendpoint at the given index. * * @param index the index * @param x the x coordinate * @param y the y coordinate */ public void setBendpoint(int index, int x, int y){ Location location = new Location(x, y); bendpoints.set(index, location); firePropertyChange(PROPERTY_BENDPOINT); } /** * Removes all bendpoints from a connection. */ public void removeAllBendpoints(){ bendpoints = new ArrayList<>(); firePropertyChange(PROPERTY_BENDPOINT); } @Override public int compareTo(Connection o) { int result = getSourceNode().compareTo(o.getSourceNode()); if (result == 0) { result = getOutput().compareTo(o.getOutput()); if (result == 0) { result = getTargetNode().compareTo(o.getTargetNode()); if (result == 0) { result = getInput().compareTo(o.getInput()); } } } return result; } }