/** * Sets the loopSide of all self-loops of the component individually, depending on the side(s) * already defined for at least one port in the component. At least one portSide must be defined, * otherwise this method will run infinitely. * * @param component The connected component to process. * @return The LoopSide that is equal to the assigned portSides. Undefined, if there is not a * common side for all loops. */ private LoopSide setPortSideByConstraint(final ConnectedSelfLoopComponent component) { // Iterator over the edges of the component. // The iterator is cycling, as there is no guarantee, that (at least) one port of the current // edge has a portSide defined. If both portSides of the current edge are UNDEFINED, we will // return to it later. final Iterator<LEdge> iter = Iterators.cycle(Lists.newArrayList(component.getEdges())); // LoopSides in this component will be collected here final EnumSet<LoopSide> loopSidesInComponent = EnumSet.noneOf(LoopSide.class); while (iter.hasNext()) { final LEdge edge = iter.next(); final PortSide sourceSide = edge.getSource().getSide(); final PortSide targetSide = edge.getTarget().getSide(); if (sourceSide == PortSide.UNDEFINED) { // source side is undefined if (targetSide != PortSide.UNDEFINED) { // only targetSide is defined. Edge becomes a sideLoop on the side of target. final LoopSide side = LoopSide.fromPortSides(targetSide); edge.setProperty(InternalProperties.SPLINE_LOOPSIDE, side); edge.getSource().setSide(targetSide); loopSidesInComponent.add(side); iter.remove(); } } else { // source side is defined if (targetSide == PortSide.UNDEFINED) { // only sourceSide is defined. Edge becomes a sideLoop on the side of source. final LoopSide side = LoopSide.fromPortSides(sourceSide); edge.setProperty(InternalProperties.SPLINE_LOOPSIDE, side); edge.getTarget().setSide(sourceSide); loopSidesInComponent.add(side); iter.remove(); } else { // both sides are defined, set edge side resulting from the combination final LoopSide side = LoopSide.fromPortSide(sourceSide, targetSide); edge.setProperty(InternalProperties.SPLINE_LOOPSIDE, side); loopSidesInComponent.add(side); iter.remove(); } } } // Now all edges have a LoopSide assigned. // Check if we can find a LoopSide for the whole component. LoopSide side; if (loopSidesInComponent.size() == 1) { side = loopSidesInComponent.iterator().next(); } else { side = LoopSide.UNDEFINED; } component.setLoopSide(side, false); return side; }
/** * Removes all sides from the list of available sides, that already have an port places on it. * Use to make sure no loops will be places on sides with ports containing non-loop edges. */ public void removeOccupiedSides() { for (final LPort port : node.getPorts()) { loopSides.removeSide(LoopSide.fromPortSides(port.getSide())); } }