Index: features/de.cau.cs.kieler.keg.feature/feature.xml =================================================================== diff -u -N -r5f201e7c9e44cbd540a990dbdd531dc90a4d0a15 -r5e866f77221b5d565bca27eb735349f3207da540 --- features/de.cau.cs.kieler.keg.feature/feature.xml (.../feature.xml) (revision 5f201e7c9e44cbd540a990dbdd531dc90a4d0a15) +++ features/de.cau.cs.kieler.keg.feature/feature.xml (.../feature.xml) (revision 5e866f77221b5d565bca27eb735349f3207da540) @@ -402,20 +402,6 @@ unpack="false"/> - - - - PORT_SIDE = new Property(PORT_SIDE_ID, PortSide.UNDEFINED); - /** layout option key: rank of a port (integer). - * @deprecated */ - public static final String PORT_RANK_ID = "de.cau.cs.kieler.portRank"; - /** port rank property. - * @deprecated */ - public static final IProperty PORT_RANK = new Property(PORT_RANK_ID, -1); - /** layout option key: shape of a node (enum). */ public static final String SHAPE_ID = "de.cau.cs.kieler.shape"; /** Index: plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/options/PortType.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/options/PortType.java (revision 595730d4fc897b3f083d31a4c9d9af3202c280b2) +++ plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/options/PortType.java (revision 0) @@ -1,42 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2010 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.kiml.options; - -/** - * Definition of port types. - * - * @kieler.rating 2011-03-14 yellow - * reviewed by cmot, cds - * @author msp - */ -public enum PortType { - - /** undefined port type. */ - UNDEFINED, - /** input port type. */ - INPUT, - /** output port type. */ - OUTPUT; - - /** - * Returns the enumeration value related to the given ordinal. - * - * @param i ordinal value - * @return the related enumeration value - */ - public static PortType valueOf(final int i) { - return values()[i]; - } - -} Index: plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/util/KimlUtil.java =================================================================== diff -u -N -rcaa3ca26cb6fca0f3f735cc068403582b354bc2c -r5e866f77221b5d565bca27eb735349f3207da540 --- plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/util/KimlUtil.java (.../KimlUtil.java) (revision caa3ca26cb6fca0f3f735cc068403582b354bc2c) +++ plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/util/KimlUtil.java (.../KimlUtil.java) (revision 5e866f77221b5d565bca27eb735349f3207da540) @@ -13,10 +13,8 @@ */ package de.cau.cs.kieler.kiml.util; -import java.io.Serializable; import java.util.Arrays; import java.util.Comparator; -import java.util.List; import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.ecore.EObject; @@ -30,7 +28,6 @@ import de.cau.cs.kieler.core.kgraph.KNode; import de.cau.cs.kieler.core.kgraph.KPort; import de.cau.cs.kieler.core.math.KVector; -import de.cau.cs.kieler.core.math.KielerMath; import de.cau.cs.kieler.kiml.LayoutDataService; import de.cau.cs.kieler.kiml.LayoutOptionData; import de.cau.cs.kieler.kiml.klayoutdata.KEdgeLayout; @@ -60,67 +57,6 @@ } /** - * Comparator class used to sort ports according to their ranks. - */ - public static class PortComparator implements Comparator, Serializable { - /** the serial version UID. */ - private static final long serialVersionUID = 7489650936528433087L; - /** indicates whether to treat ranks in forward direction. */ - private boolean forward; - /** horizontal or vertical layout direction. */ - private Direction layoutDirection; - - /** - * Creates a port comparator for the given setting. - * - * @param theforward indicates whether to treat ranks in forward - * direction - * @param thelayoutDirection horizontal or vertical layout direction - */ - public PortComparator(final boolean theforward, final Direction thelayoutDirection) { - this.forward = theforward; - this.layoutDirection = thelayoutDirection; - } - - /** - * {@inheritDoc} - */ - public int compare(final KPort port1, final KPort port2) { - KShapeLayout layout1 = port1.getData(KShapeLayout.class); - KShapeLayout layout2 = port2.getData(KShapeLayout.class); - int rank1 = layout1.getProperty(LayoutOptions.PORT_RANK); - int rank2 = layout2.getProperty(LayoutOptions.PORT_RANK); - PortSide side1 = layout1.getProperty(LayoutOptions.PORT_SIDE); - PortSide side2 = layout2.getProperty(LayoutOptions.PORT_SIDE); - if (side1 == side2) { - return layoutDirection == Direction.DOWN && !forward - || layoutDirection == Direction.RIGHT && forward ? rank1 - rank2 - : rank2 - rank1; - } else if (layoutDirection == Direction.DOWN) { - if (forward) { - return side1 == PortSide.NORTH || side1 == PortSide.EAST - && (side2 == PortSide.SOUTH || side2 == PortSide.WEST) - || side1 == PortSide.SOUTH && side2 == PortSide.WEST ? 1 : -1; - } else { - return side1 == PortSide.SOUTH || side1 == PortSide.EAST - && (side2 == PortSide.NORTH || side2 == PortSide.WEST) - || side1 == PortSide.NORTH && side2 == PortSide.WEST ? 1 : -1; - } - } else { - if (forward) { - return side1 == PortSide.WEST || side1 == PortSide.SOUTH - && (side2 == PortSide.EAST || side2 == PortSide.NORTH) - || side1 == PortSide.EAST && side2 == PortSide.NORTH ? 1 : -1; - } else { - return side1 == PortSide.EAST || side1 == PortSide.SOUTH - && (side2 == PortSide.WEST || side2 == PortSide.NORTH) - || side1 == PortSide.WEST && side2 == PortSide.NORTH ? 1 : -1; - } - } - } - } - - /** * Creates a KNode, initializes some attributes, and returns it. * * @return an initialized KNode @@ -281,18 +217,13 @@ public int compare(final KPort port1, final KPort port2) { KShapeLayout port1Layout = port1.getData(KShapeLayout.class); PortSide port1Side = port1Layout.getProperty(LayoutOptions.PORT_SIDE); - int port1Rank = port1Layout.getProperty(LayoutOptions.PORT_RANK); KShapeLayout port2Layout = port2.getData(KShapeLayout.class); PortSide port2Side = port2Layout.getProperty(LayoutOptions.PORT_SIDE); - int port2Rank = port2Layout.getProperty(LayoutOptions.PORT_RANK); int result = 0; switch (port1Side) { case NORTH: if (port2Side == PortSide.NORTH) { result = Float.compare(port1Layout.getXpos(), port2Layout.getXpos()); - if (result == 0) { - result = port1Rank > port2Rank ? 1 : (port1Rank < port2Rank ? -1 : 0); - } } else { result = -1; } @@ -302,9 +233,6 @@ result = 1; } else if (port2Side == PortSide.EAST) { result = Float.compare(port1Layout.getYpos(), port2Layout.getYpos()); - if (result == 0) { - result = port1Rank > port2Rank ? 1 : (port1Rank < port2Rank ? -1 : 0); - } } else { result = -1; } @@ -314,9 +242,6 @@ result = 1; } else if (port2Side == PortSide.SOUTH) { result = Float.compare(port2Layout.getXpos(), port1Layout.getXpos()); - if (result == 0) { - result = port1Rank > port2Rank ? 1 : (port1Rank < port2Rank ? -1 : 0); - } } else { result = -1; } @@ -327,9 +252,6 @@ result = 1; } else if (port2Side == PortSide.WEST) { result = Float.compare(port2Layout.getYpos(), port1Layout.getYpos()); - if (result == 0) { - result = port1Rank > port2Rank ? 1 : (port1Rank < port2Rank ? -1 : 0); - } } else { result = -1; } @@ -342,120 +264,6 @@ return ports; } - /** - * Sets port ranks for all ports of the given node according to their - * relative positions. - * - * @param node node for which port ranks shall be set - */ - public static void calcPortRanks(final KNode node) { - // sort the ports according to their positions - KPort[] ports = getSortedPorts(node); - // assign ranks according to the new order - for (int i = 0; i < ports.length; i++) { - ports[i].getData(KShapeLayout.class).setProperty(LayoutOptions.PORT_RANK, i); - } - } - - /** - * Fills all missing data for the ports of the given node, such as port - * sides and port ranks. - * - * @param node node for which port data shall be created - * @param direction layout direction - */ - public static void fillPortInfo(final KNode node, final Direction direction) { - KGraphData layoutData = node.getData(KShapeLayout.class); - PortConstraints portConstraints = layoutData.getProperty(LayoutOptions.PORT_CONSTRAINTS); - if (portConstraints == PortConstraints.FREE) { - // set port sides according to layout direction - switch (direction) { - case DOWN: - for (KPort port : node.getPorts()) { - port.getData(KShapeLayout.class).setProperty( - LayoutOptions.PORT_SIDE, calcFlow(port) < 0 - ? PortSide.NORTH : PortSide.SOUTH); - } - break; - case UP: - for (KPort port : node.getPorts()) { - port.getData(KShapeLayout.class).setProperty( - LayoutOptions.PORT_SIDE, calcFlow(port) < 0 - ? PortSide.SOUTH : PortSide.NORTH); - } - break; - case LEFT: - for (KPort port : node.getPorts()) { - port.getData(KShapeLayout.class).setProperty( - LayoutOptions.PORT_SIDE, calcFlow(port) < 0 - ? PortSide.EAST : PortSide.WEST); - } - break; - default: - for (KPort port : node.getPorts()) { - port.getData(KShapeLayout.class).setProperty(LayoutOptions.PORT_SIDE, - calcFlow(port) < 0 - ? PortSide.WEST : PortSide.EAST); - } - break; - } - layoutData.setProperty(LayoutOptions.PORT_CONSTRAINTS, PortConstraints.FIXED_SIDE); - } else if (portConstraints != PortConstraints.UNDEFINED) { - // set port sides and ranks according to relative position - boolean ranksUndefined = false; - for (KPort port : node.getPorts()) { - KGraphData portLayout = port.getData(KShapeLayout.class); - if (portLayout.getProperty(LayoutOptions.PORT_RANK) < 0) { - ranksUndefined = true; - } - if (portLayout.getProperty(LayoutOptions.PORT_SIDE) == PortSide.UNDEFINED) { - portLayout.setProperty(LayoutOptions.PORT_SIDE, calcPortSide(port, direction)); - } - } - if (ranksUndefined) { - calcPortRanks(node); - } - } - } - - /** - * Determines positions of a sorted set of points by placing them with equal - * distances. - * - * @param points list of points - * @param minPos minimal position for placing - * @param maxPos maximal position for placing - * @param offset offset to be added to positions - * @param vertical if true, the vertical position is processed, else the - * horizontal position is processed - * @param forward if true, ports are placed from the minimum to the maximum - * position - */ - public static void placePoints(final List points, final float minPos, - final float maxPos, final float offset, final boolean vertical, - final boolean forward) { - float dist = (maxPos - minPos) / (points.size() + 1); - float pos; - if (forward) { - pos = minPos + offset; - } else { - pos = maxPos + offset; - dist = -dist; - } - - if (vertical) { - for (KPoint point : points) { - pos += dist; - point.setY(pos); - } - } else { - for (KPoint point : points) { - pos += dist; - point.setX(pos); - } - } - } - /** minimal size of a node. */ private static final float MIN_NODE_SIZE = 20.0f; @@ -635,46 +443,6 @@ } /** - * Determines the flow of the given port, that is the difference between the - * number of outgoing edges and the number of incoming edges. Edges that - * connect to descendant nodes are counted in their reverse direction. - * - * @param port port for which the flow shall be calculated - * @return difference between number of outgoing and incoming edges - */ - public static int calcFlow(final KPort port) { - int flow = 0; - for (KEdge edge : port.getEdges()) { - KPort sourcePort = edge.getSourcePort(); - KPort targetPort = edge.getTargetPort(); - KNode otherNode = null; - if (sourcePort == port) { - otherNode = edge.getTarget(); - } else if (targetPort == port) { - otherNode = edge.getSource(); - } - if (otherNode != null) { - if (isDescendant(otherNode, port.getNode())) { - if (sourcePort == port) { - flow--; - } - if (targetPort == port) { - flow++; - } - } else { - if (sourcePort == port) { - flow++; - } - if (targetPort == port) { - flow--; - } - } - } - } - return flow; - } - - /** * Determines whether the given child node is a descendant of the parent * node. * Index: plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/KGraphImporter.java =================================================================== diff -u -N -rcaa3ca26cb6fca0f3f735cc068403582b354bc2c -r5e866f77221b5d565bca27eb735349f3207da540 --- plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/KGraphImporter.java (.../KGraphImporter.java) (revision caa3ca26cb6fca0f3f735cc068403582b354bc2c) +++ plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/KGraphImporter.java (.../KGraphImporter.java) (revision 5e866f77221b5d565bca27eb735349f3207da540) @@ -37,7 +37,6 @@ import de.cau.cs.kieler.kiml.options.LayoutOptions; import de.cau.cs.kieler.kiml.options.PortConstraints; import de.cau.cs.kieler.kiml.options.PortSide; -import de.cau.cs.kieler.kiml.options.PortType; import de.cau.cs.kieler.kiml.options.SizeConstraint; import de.cau.cs.kieler.kiml.util.KimlUtil; import de.cau.cs.kieler.klay.layered.graph.LInsets; @@ -49,6 +48,7 @@ import de.cau.cs.kieler.klay.layered.graph.LayeredGraph; import de.cau.cs.kieler.klay.layered.p3order.CrossingMinimizationStrategy; import de.cau.cs.kieler.klay.layered.properties.GraphProperties; +import de.cau.cs.kieler.klay.layered.properties.PortType; import de.cau.cs.kieler.klay.layered.properties.Properties; /** Index: plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/Util.java =================================================================== diff -u -N -r0c4fc9e7150584c259cfa8c8250baca5669f50ab -r5e866f77221b5d565bca27eb735349f3207da540 --- plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/Util.java (.../Util.java) (revision 0c4fc9e7150584c259cfa8c8250baca5669f50ab) +++ plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/Util.java (.../Util.java) (revision 5e866f77221b5d565bca27eb735349f3207da540) @@ -22,13 +22,13 @@ import de.cau.cs.kieler.core.kgraph.KPort; import de.cau.cs.kieler.core.math.KVector; import de.cau.cs.kieler.kiml.options.PortSide; -import de.cau.cs.kieler.kiml.options.PortType; import de.cau.cs.kieler.kiml.util.KimlUtil; import de.cau.cs.kieler.klay.layered.graph.LGraphElement; import de.cau.cs.kieler.klay.layered.graph.LNode; import de.cau.cs.kieler.klay.layered.graph.LPort; import de.cau.cs.kieler.klay.layered.graph.LayeredGraph; import de.cau.cs.kieler.klay.layered.properties.NodeType; +import de.cau.cs.kieler.klay.layered.properties.PortType; import de.cau.cs.kieler.klay.layered.properties.Properties; /** Index: plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/graph/LEdge.java =================================================================== diff -u -N -raab9be51f79008721a116e38865288bbe9e7422e -r5e866f77221b5d565bca27eb735349f3207da540 --- plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/graph/LEdge.java (.../LEdge.java) (revision aab9be51f79008721a116e38865288bbe9e7422e) +++ plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/graph/LEdge.java (.../LEdge.java) (revision 5e866f77221b5d565bca27eb735349f3207da540) @@ -19,8 +19,8 @@ import de.cau.cs.kieler.core.math.KVector; import de.cau.cs.kieler.core.math.KVectorChain; import de.cau.cs.kieler.kiml.options.PortSide; -import de.cau.cs.kieler.kiml.options.PortType; import de.cau.cs.kieler.klay.layered.Util; +import de.cau.cs.kieler.klay.layered.properties.PortType; import de.cau.cs.kieler.klay.layered.properties.Properties; /** Index: plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/graph/LNode.java =================================================================== diff -u -N -rc6d39664cfb271f5286db0327ecaca0c47e77c8b -r5e866f77221b5d565bca27eb735349f3207da540 --- plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/graph/LNode.java (.../LNode.java) (revision c6d39664cfb271f5286db0327ecaca0c47e77c8b) +++ plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/graph/LNode.java (.../LNode.java) (revision 5e866f77221b5d565bca27eb735349f3207da540) @@ -24,7 +24,7 @@ import de.cau.cs.kieler.core.util.FilteredIterator; import de.cau.cs.kieler.core.util.ICondition; import de.cau.cs.kieler.kiml.options.PortSide; -import de.cau.cs.kieler.kiml.options.PortType; +import de.cau.cs.kieler.klay.layered.properties.PortType; import de.cau.cs.kieler.klay.layered.properties.Properties; /** Index: plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/graph/LPort.java =================================================================== diff -u -N -rc6d39664cfb271f5286db0327ecaca0c47e77c8b -r5e866f77221b5d565bca27eb735349f3207da540 --- plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/graph/LPort.java (.../LPort.java) (revision c6d39664cfb271f5286db0327ecaca0c47e77c8b) +++ plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/graph/LPort.java (.../LPort.java) (revision 5e866f77221b5d565bca27eb735349f3207da540) @@ -21,7 +21,7 @@ import de.cau.cs.kieler.core.util.ICondition; import de.cau.cs.kieler.kiml.options.PortSide; -import de.cau.cs.kieler.kiml.options.PortType; +import de.cau.cs.kieler.klay.layered.properties.PortType; /** * A port in a layered graph. The position of the port is relative to the upper Index: plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/intermediate/EdgeAndLayerConstraintEdgeReverser.java =================================================================== diff -u -N -raab9be51f79008721a116e38865288bbe9e7422e -r5e866f77221b5d565bca27eb735349f3207da540 --- plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/intermediate/EdgeAndLayerConstraintEdgeReverser.java (.../EdgeAndLayerConstraintEdgeReverser.java) (revision aab9be51f79008721a116e38865288bbe9e7422e) +++ plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/intermediate/EdgeAndLayerConstraintEdgeReverser.java (.../EdgeAndLayerConstraintEdgeReverser.java) (revision 5e866f77221b5d565bca27eb735349f3207da540) @@ -18,14 +18,14 @@ import de.cau.cs.kieler.core.alg.AbstractAlgorithm; import de.cau.cs.kieler.kiml.options.LayoutOptions; import de.cau.cs.kieler.kiml.options.PortSide; -import de.cau.cs.kieler.kiml.options.PortType; import de.cau.cs.kieler.klay.layered.ILayoutProcessor; import de.cau.cs.kieler.klay.layered.graph.LEdge; import de.cau.cs.kieler.klay.layered.graph.LNode; import de.cau.cs.kieler.klay.layered.graph.LPort; import de.cau.cs.kieler.klay.layered.graph.LayeredGraph; import de.cau.cs.kieler.klay.layered.properties.EdgeConstraint; import de.cau.cs.kieler.klay.layered.properties.LayerConstraint; +import de.cau.cs.kieler.klay.layered.properties.PortType; import de.cau.cs.kieler.klay.layered.properties.Properties; /** Index: plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/intermediate/InvertedPortProcessor.java =================================================================== diff -u -N -r9ce91b0aace6eece883c125b81eec5d44ab66a91 -r5e866f77221b5d565bca27eb735349f3207da540 --- plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/intermediate/InvertedPortProcessor.java (.../InvertedPortProcessor.java) (revision 9ce91b0aace6eece883c125b81eec5d44ab66a91) +++ plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/intermediate/InvertedPortProcessor.java (.../InvertedPortProcessor.java) (revision 5e866f77221b5d565bca27eb735349f3207da540) @@ -21,14 +21,14 @@ import de.cau.cs.kieler.kiml.options.LayoutOptions; import de.cau.cs.kieler.kiml.options.PortConstraints; import de.cau.cs.kieler.kiml.options.PortSide; -import de.cau.cs.kieler.kiml.options.PortType; import de.cau.cs.kieler.klay.layered.ILayoutProcessor; import de.cau.cs.kieler.klay.layered.graph.LEdge; import de.cau.cs.kieler.klay.layered.graph.LNode; import de.cau.cs.kieler.klay.layered.graph.LPort; import de.cau.cs.kieler.klay.layered.graph.Layer; import de.cau.cs.kieler.klay.layered.graph.LayeredGraph; import de.cau.cs.kieler.klay.layered.properties.NodeType; +import de.cau.cs.kieler.klay.layered.properties.PortType; import de.cau.cs.kieler.klay.layered.properties.Properties; /** Index: plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/p1cycles/InteractiveCycleBreaker.java =================================================================== diff -u -N -rba2e22c3a07ef8e12c8ccb57a9d20bf75dc80a36 -r5e866f77221b5d565bca27eb735349f3207da540 --- plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/p1cycles/InteractiveCycleBreaker.java (.../InteractiveCycleBreaker.java) (revision ba2e22c3a07ef8e12c8ccb57a9d20bf75dc80a36) +++ plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/p1cycles/InteractiveCycleBreaker.java (.../InteractiveCycleBreaker.java) (revision 5e866f77221b5d565bca27eb735349f3207da540) @@ -18,14 +18,14 @@ import java.util.List; import de.cau.cs.kieler.core.alg.AbstractAlgorithm; -import de.cau.cs.kieler.kiml.options.PortType; import de.cau.cs.kieler.klay.layered.ILayoutPhase; import de.cau.cs.kieler.klay.layered.IntermediateProcessingStrategy; import de.cau.cs.kieler.klay.layered.graph.LEdge; import de.cau.cs.kieler.klay.layered.graph.LNode; import de.cau.cs.kieler.klay.layered.graph.LPort; import de.cau.cs.kieler.klay.layered.graph.LayeredGraph; import de.cau.cs.kieler.klay.layered.intermediate.IntermediateLayoutProcessor; +import de.cau.cs.kieler.klay.layered.properties.PortType; /** * A cycle breaker that responds to user interaction by respecting the direction of Index: plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/p2layers/InteractiveLayerer.java =================================================================== diff -u -N -rf5f4301d9feaf3dc7191c87fe01167843b6652ce -r5e866f77221b5d565bca27eb735349f3207da540 --- plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/p2layers/InteractiveLayerer.java (.../InteractiveLayerer.java) (revision f5f4301d9feaf3dc7191c87fe01167843b6652ce) +++ plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/p2layers/InteractiveLayerer.java (.../InteractiveLayerer.java) (revision 5e866f77221b5d565bca27eb735349f3207da540) @@ -18,14 +18,14 @@ import java.util.ListIterator; import de.cau.cs.kieler.core.alg.AbstractAlgorithm; -import de.cau.cs.kieler.kiml.options.PortType; import de.cau.cs.kieler.klay.layered.ILayoutPhase; import de.cau.cs.kieler.klay.layered.IntermediateProcessingStrategy; import de.cau.cs.kieler.klay.layered.graph.LEdge; import de.cau.cs.kieler.klay.layered.graph.LNode; import de.cau.cs.kieler.klay.layered.graph.LPort; import de.cau.cs.kieler.klay.layered.graph.Layer; import de.cau.cs.kieler.klay.layered.graph.LayeredGraph; +import de.cau.cs.kieler.klay.layered.properties.PortType; /** * A node layerer that allows user interaction by respecting previous node positions. Index: plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/p3order/AbstractCrossingMinimizer.java =================================================================== diff -u -N -rf5f4301d9feaf3dc7191c87fe01167843b6652ce -r5e866f77221b5d565bca27eb735349f3207da540 --- plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/p3order/AbstractCrossingMinimizer.java (.../AbstractCrossingMinimizer.java) (revision f5f4301d9feaf3dc7191c87fe01167843b6652ce) +++ plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/p3order/AbstractCrossingMinimizer.java (.../AbstractCrossingMinimizer.java) (revision 5e866f77221b5d565bca27eb735349f3207da540) @@ -23,13 +23,13 @@ import de.cau.cs.kieler.kiml.options.LayoutOptions; import de.cau.cs.kieler.kiml.options.PortConstraints; import de.cau.cs.kieler.kiml.options.PortSide; -import de.cau.cs.kieler.kiml.options.PortType; import de.cau.cs.kieler.klay.layered.ILayoutPhase; import de.cau.cs.kieler.klay.layered.IntermediateProcessingStrategy; import de.cau.cs.kieler.klay.layered.graph.LNode; import de.cau.cs.kieler.klay.layered.graph.LPort; import de.cau.cs.kieler.klay.layered.graph.LayeredGraph; import de.cau.cs.kieler.klay.layered.intermediate.IntermediateLayoutProcessor; +import de.cau.cs.kieler.klay.layered.properties.PortType; /** * Abstract superclass for crossing minimizer implementations. Contains commonly used Index: plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/p3order/BarycenterHeuristic.java =================================================================== diff -u -N -r225b9aae79bbce7cf99a988edd5f11613effe390 -r5e866f77221b5d565bca27eb735349f3207da540 --- plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/p3order/BarycenterHeuristic.java (.../BarycenterHeuristic.java) (revision 225b9aae79bbce7cf99a988edd5f11613effe390) +++ plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/p3order/BarycenterHeuristic.java (.../BarycenterHeuristic.java) (revision 5e866f77221b5d565bca27eb735349f3207da540) @@ -25,9 +25,9 @@ import com.google.common.collect.Multimap; -import de.cau.cs.kieler.kiml.options.PortType; import de.cau.cs.kieler.klay.layered.graph.LNode; import de.cau.cs.kieler.klay.layered.graph.LPort; +import de.cau.cs.kieler.klay.layered.properties.PortType; import de.cau.cs.kieler.klay.layered.properties.Properties; /** Index: plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/p3order/LayerSweepCrossingMinimizer.java =================================================================== diff -u -N -r561a10c7d8fa57ccf907c8ea111d5591173f4956 -r5e866f77221b5d565bca27eb735349f3207da540 --- plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/p3order/LayerSweepCrossingMinimizer.java (.../LayerSweepCrossingMinimizer.java) (revision 561a10c7d8fa57ccf907c8ea111d5591173f4956) +++ plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/p3order/LayerSweepCrossingMinimizer.java (.../LayerSweepCrossingMinimizer.java) (revision 5e866f77221b5d565bca27eb735349f3207da540) @@ -27,13 +27,13 @@ import de.cau.cs.kieler.kiml.klayoutdata.KShapeLayout; import de.cau.cs.kieler.kiml.options.LayoutOptions; import de.cau.cs.kieler.kiml.options.PortSide; -import de.cau.cs.kieler.kiml.options.PortType; import de.cau.cs.kieler.klay.layered.graph.LEdge; import de.cau.cs.kieler.klay.layered.graph.LNode; import de.cau.cs.kieler.klay.layered.graph.LPort; import de.cau.cs.kieler.klay.layered.graph.Layer; import de.cau.cs.kieler.klay.layered.graph.LayeredGraph; import de.cau.cs.kieler.klay.layered.properties.NodeType; +import de.cau.cs.kieler.klay.layered.properties.PortType; import de.cau.cs.kieler.klay.layered.properties.Properties; /** Index: plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/p3order/NodeRelativePortDistributor.java =================================================================== diff -u -N -r2d4cf40d92f3484ce72cb88c9a101783464a5b12 -r5e866f77221b5d565bca27eb735349f3207da540 --- plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/p3order/NodeRelativePortDistributor.java (.../NodeRelativePortDistributor.java) (revision 2d4cf40d92f3484ce72cb88c9a101783464a5b12) +++ plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/p3order/NodeRelativePortDistributor.java (.../NodeRelativePortDistributor.java) (revision 5e866f77221b5d565bca27eb735349f3207da540) @@ -22,9 +22,9 @@ import de.cau.cs.kieler.kiml.options.LayoutOptions; import de.cau.cs.kieler.kiml.options.PortConstraints; import de.cau.cs.kieler.kiml.options.PortSide; -import de.cau.cs.kieler.kiml.options.PortType; import de.cau.cs.kieler.klay.layered.graph.LNode; import de.cau.cs.kieler.klay.layered.graph.LPort; +import de.cau.cs.kieler.klay.layered.properties.PortType; /** * Calculates port ranks and distributes ports in a node-relative way. This is in fact the original Index: plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/p5edges/OrthogonalRoutingGenerator.java =================================================================== diff -u -N -r3bc4fa083fefa9db4f9c8d65f2953bbb5c3c28d9 -r5e866f77221b5d565bca27eb735349f3207da540 --- plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/p5edges/OrthogonalRoutingGenerator.java (.../OrthogonalRoutingGenerator.java) (revision 3bc4fa083fefa9db4f9c8d65f2953bbb5c3c28d9) +++ plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/p5edges/OrthogonalRoutingGenerator.java (.../OrthogonalRoutingGenerator.java) (revision 5e866f77221b5d565bca27eb735349f3207da540) @@ -28,12 +28,12 @@ import de.cau.cs.kieler.core.math.KVector; import de.cau.cs.kieler.kiml.options.PortSide; -import de.cau.cs.kieler.kiml.options.PortType; import de.cau.cs.kieler.klay.layered.Util; import de.cau.cs.kieler.klay.layered.graph.LEdge; import de.cau.cs.kieler.klay.layered.graph.LNode; import de.cau.cs.kieler.klay.layered.graph.LPort; import de.cau.cs.kieler.klay.layered.graph.LayeredGraph; +import de.cau.cs.kieler.klay.layered.properties.PortType; /** * Edge routing implementation that creates orthogonal bend points. Inspired by Index: plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/properties/PortType.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/properties/PortType.java (revision 0) +++ plugins/de.cau.cs.kieler.klay.layered/src/de/cau/cs/kieler/klay/layered/properties/PortType.java (revision 5e866f77221b5d565bca27eb735349f3207da540) @@ -0,0 +1,42 @@ +/* + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient + * + * http://www.informatik.uni-kiel.de/rtsys/kieler/ + * + * Copyright 2010 by + * + Christian-Albrechts-University of Kiel + * + Department of Computer Science + * + Real-Time and Embedded Systems Group + * + * This code is provided under the terms of the Eclipse Public License (EPL). + * See the file epl-v10.html for the license text. + */ +package de.cau.cs.kieler.klay.layered.properties; + +/** + * Definition of port types. + * + * @kieler.rating 2011-03-14 yellow + * reviewed by cmot, cds + * @author msp + */ +public enum PortType { + + /** undefined port type. */ + UNDEFINED, + /** input port type. */ + INPUT, + /** output port type. */ + OUTPUT; + + /** + * Returns the enumeration value related to the given ordinal. + * + * @param i ordinal value + * @return the related enumeration value + */ + public static PortType valueOf(final int i) { + return values()[i]; + } + +} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/.classpath =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/.classpath (revision 793f0325b52206c2fa9caf5c639651f6605a9dc7) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/.classpath (revision 0) @@ -1,7 +0,0 @@ - - - - - - - Index: plugins/de.cau.cs.kieler.klodd.hierarchical/.project =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/.project (revision cf51ddd2cf94979c15aa8cbcf4e1f0951db33e50) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/.project (revision 0) @@ -1,34 +0,0 @@ - - - de.cau.cs.kieler.klodd.hierarchical - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - net.sf.eclipsecs.core.CheckstyleBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - net.sf.eclipsecs.core.CheckstyleNature - - Index: plugins/de.cau.cs.kieler.klodd.hierarchical/.settings/org.eclipse.jdt.core.prefs =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/.settings/org.eclipse.jdt.core.prefs (revision 5aa9dede5708c0f79d6f1ea6061c52bfdc911912) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/.settings/org.eclipse.jdt.core.prefs (revision 0) @@ -1,12 +0,0 @@ -#Fri Jan 09 13:44:25 CET 2009 -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.5 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.5 Index: plugins/de.cau.cs.kieler.klodd.hierarchical/.settings/org.eclipse.jdt.ui.prefs =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/.settings/org.eclipse.jdt.ui.prefs (revision 5aa9dede5708c0f79d6f1ea6061c52bfdc911912) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/.settings/org.eclipse.jdt.ui.prefs (revision 0) @@ -1,3 +0,0 @@ -#Tue Nov 18 11:56:51 CET 2008 -eclipse.preferences.version=1 -org.eclipse.jdt.ui.text.custom_code_templates= Index: plugins/de.cau.cs.kieler.klodd.hierarchical/META-INF/MANIFEST.MF =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/META-INF/MANIFEST.MF (revision c0395e06370c524c7d2cefd7be19bef58b83d802) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/META-INF/MANIFEST.MF (revision 0) @@ -1,16 +0,0 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: KIELER Hierarchical Dataflow Layout -Bundle-SymbolicName: de.cau.cs.kieler.klodd.hierarchical;singleton:=true -Bundle-Version: 0.7.2.qualifier -Require-Bundle: de.cau.cs.kieler.core, - de.cau.cs.kieler.kiml, - de.cau.cs.kieler.core.kgraph -Export-Package: de.cau.cs.kieler.klodd.hierarchical; - uses:="de.cau.cs.kieler.kiml.services, - de.cau.cs.kieler.core, - de.cau.cs.kieler.kiml.options, - de.cau.cs.kieler.core.alg, - de.cau.cs.kieler.core.kgraph" -Bundle-Vendor: Christian-Albrechts-Universität zu Kiel -Bundle-RequiredExecutionEnvironment: J2SE-1.5 Index: plugins/de.cau.cs.kieler.klodd.hierarchical/README.txt =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/README.txt (revision 2f10ad81a7e7fca32407898dbc66cb8332681da1) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/README.txt (revision 0) @@ -1,7 +0,0 @@ -| de.cau.cs.kieler.klodd.hierarchical -\______________________________________ - -Hierarchical layout algorithm for dataflow diagrams. Comes with the KIELER -Layout of Dataflow Diagrams (KLoDD) subproject. The algorithm is embedded -in KIML, but can also be used as a stand-alone library, as it has only few -dependencies to Eclipse. Index: plugins/de.cau.cs.kieler.klodd.hierarchical/build.properties =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/build.properties (revision 5aa9dede5708c0f79d6f1ea6061c52bfdc911912) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/build.properties (revision 0) @@ -1,6 +0,0 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - epl-v10.html -src.includes = epl-v10.html Index: plugins/de.cau.cs.kieler.klodd.hierarchical/epl-v10.html =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/epl-v10.html (revision 5aa9dede5708c0f79d6f1ea6061c52bfdc911912) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/epl-v10.html (revision 0) @@ -1,262 +0,0 @@ - - - - - - -Eclipse Public License - Version 1.0 - - - - - - -

Eclipse Public License - v 1.0

- -

THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE -PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR -DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS -AGREEMENT.

- -

1. DEFINITIONS

- -

"Contribution" means:

- -

a) in the case of the initial Contributor, the initial -code and documentation distributed under this Agreement, and

-

b) in the case of each subsequent Contributor:

- -

i) changes to the Program, and

-

ii) additions to the Program;

-

where such changes and/or additions to the Program -originate from and are distributed by that particular Contributor. A -Contribution 'originates' from a Contributor if it was added to the -Program by such Contributor itself or anyone acting on such -Contributor's behalf. Contributions do not include additions to the -Program which: (i) are separate modules of software distributed in -conjunction with the Program under their own license agreement, and (ii) -are not derivative works of the Program.

- -

"Contributor" means any person or entity that distributes -the Program.

- -

"Licensed Patents" mean patent claims licensable by a -Contributor which are necessarily infringed by the use or sale of its -Contribution alone or when combined with the Program.

- -

"Program" means the Contributions distributed in accordance -with this Agreement.

- -

"Recipient" means anyone who receives the Program under -this Agreement, including all Contributors.

- -

2. GRANT OF RIGHTS

- -

a) Subject to the terms of this Agreement, each -Contributor hereby grants Recipient a non-exclusive, worldwide, -royalty-free copyright license to reproduce, prepare derivative works -of, publicly display, publicly perform, distribute and sublicense the -Contribution of such Contributor, if any, and such derivative works, in -source code and object code form.

- -

b) Subject to the terms of this Agreement, each -Contributor hereby grants Recipient a non-exclusive, worldwide, -royalty-free patent license under Licensed Patents to make, use, sell, -offer to sell, import and otherwise transfer the Contribution of such -Contributor, if any, in source code and object code form. This patent -license shall apply to the combination of the Contribution and the -Program if, at the time the Contribution is added by the Contributor, -such addition of the Contribution causes such combination to be covered -by the Licensed Patents. The patent license shall not apply to any other -combinations which include the Contribution. No hardware per se is -licensed hereunder.

- -

c) Recipient understands that although each Contributor -grants the licenses to its Contributions set forth herein, no assurances -are provided by any Contributor that the Program does not infringe the -patent or other intellectual property rights of any other entity. Each -Contributor disclaims any liability to Recipient for claims brought by -any other entity based on infringement of intellectual property rights -or otherwise. As a condition to exercising the rights and licenses -granted hereunder, each Recipient hereby assumes sole responsibility to -secure any other intellectual property rights needed, if any. For -example, if a third party patent license is required to allow Recipient -to distribute the Program, it is Recipient's responsibility to acquire -that license before distributing the Program.

- -

d) Each Contributor represents that to its knowledge it -has sufficient copyright rights in its Contribution, if any, to grant -the copyright license set forth in this Agreement.

- -

3. REQUIREMENTS

- -

A Contributor may choose to distribute the Program in object code -form under its own license agreement, provided that:

- -

a) it complies with the terms and conditions of this -Agreement; and

- -

b) its license agreement:

- -

i) effectively disclaims on behalf of all Contributors -all warranties and conditions, express and implied, including warranties -or conditions of title and non-infringement, and implied warranties or -conditions of merchantability and fitness for a particular purpose;

- -

ii) effectively excludes on behalf of all Contributors -all liability for damages, including direct, indirect, special, -incidental and consequential damages, such as lost profits;

- -

iii) states that any provisions which differ from this -Agreement are offered by that Contributor alone and not by any other -party; and

- -

iv) states that source code for the Program is available -from such Contributor, and informs licensees how to obtain it in a -reasonable manner on or through a medium customarily used for software -exchange.

- -

When the Program is made available in source code form:

- -

a) it must be made available under this Agreement; and

- -

b) a copy of this Agreement must be included with each -copy of the Program.

- -

Contributors may not remove or alter any copyright notices contained -within the Program.

- -

Each Contributor must identify itself as the originator of its -Contribution, if any, in a manner that reasonably allows subsequent -Recipients to identify the originator of the Contribution.

- -

4. COMMERCIAL DISTRIBUTION

- -

Commercial distributors of software may accept certain -responsibilities with respect to end users, business partners and the -like. While this license is intended to facilitate the commercial use of -the Program, the Contributor who includes the Program in a commercial -product offering should do so in a manner which does not create -potential liability for other Contributors. Therefore, if a Contributor -includes the Program in a commercial product offering, such Contributor -("Commercial Contributor") hereby agrees to defend and -indemnify every other Contributor ("Indemnified Contributor") -against any losses, damages and costs (collectively "Losses") -arising from claims, lawsuits and other legal actions brought by a third -party against the Indemnified Contributor to the extent caused by the -acts or omissions of such Commercial Contributor in connection with its -distribution of the Program in a commercial product offering. The -obligations in this section do not apply to any claims or Losses -relating to any actual or alleged intellectual property infringement. In -order to qualify, an Indemnified Contributor must: a) promptly notify -the Commercial Contributor in writing of such claim, and b) allow the -Commercial Contributor to control, and cooperate with the Commercial -Contributor in, the defense and any related settlement negotiations. The -Indemnified Contributor may participate in any such claim at its own -expense.

- -

For example, a Contributor might include the Program in a commercial -product offering, Product X. That Contributor is then a Commercial -Contributor. If that Commercial Contributor then makes performance -claims, or offers warranties related to Product X, those performance -claims and warranties are such Commercial Contributor's responsibility -alone. Under this section, the Commercial Contributor would have to -defend claims against the other Contributors related to those -performance claims and warranties, and if a court requires any other -Contributor to pay any damages as a result, the Commercial Contributor -must pay those damages.

- -

5. NO WARRANTY

- -

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS -PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS -OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, -ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY -OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely -responsible for determining the appropriateness of using and -distributing the Program and assumes all risks associated with its -exercise of rights under this Agreement , including but not limited to -the risks and costs of program errors, compliance with applicable laws, -damage to or loss of data, programs or equipment, and unavailability or -interruption of operations.

- -

6. DISCLAIMER OF LIABILITY

- -

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT -NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING -WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR -DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED -HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

- -

7. GENERAL

- -

If any provision of this Agreement is invalid or unenforceable under -applicable law, it shall not affect the validity or enforceability of -the remainder of the terms of this Agreement, and without further action -by the parties hereto, such provision shall be reformed to the minimum -extent necessary to make such provision valid and enforceable.

- -

If Recipient institutes patent litigation against any entity -(including a cross-claim or counterclaim in a lawsuit) alleging that the -Program itself (excluding combinations of the Program with other -software or hardware) infringes such Recipient's patent(s), then such -Recipient's rights granted under Section 2(b) shall terminate as of the -date such litigation is filed.

- -

All Recipient's rights under this Agreement shall terminate if it -fails to comply with any of the material terms or conditions of this -Agreement and does not cure such failure in a reasonable period of time -after becoming aware of such noncompliance. If all Recipient's rights -under this Agreement terminate, Recipient agrees to cease use and -distribution of the Program as soon as reasonably practicable. However, -Recipient's obligations under this Agreement and any licenses granted by -Recipient relating to the Program shall continue and survive.

- -

Everyone is permitted to copy and distribute copies of this -Agreement, but in order to avoid inconsistency the Agreement is -copyrighted and may only be modified in the following manner. The -Agreement Steward reserves the right to publish new versions (including -revisions) of this Agreement from time to time. No one other than the -Agreement Steward has the right to modify this Agreement. The Eclipse -Foundation is the initial Agreement Steward. The Eclipse Foundation may -assign the responsibility to serve as the Agreement Steward to a -suitable separate entity. Each new version of the Agreement will be -given a distinguishing version number. The Program (including -Contributions) may always be distributed subject to the version of the -Agreement under which it was received. In addition, after a new version -of the Agreement is published, Contributor may elect to distribute the -Program (including its Contributions) under the new version. Except as -expressly stated in Sections 2(a) and 2(b) above, Recipient receives no -rights or licenses to the intellectual property of any Contributor under -this Agreement, whether expressly, by implication, estoppel or -otherwise. All rights in the Program not expressly granted under this -Agreement are reserved.

- -

This Agreement is governed by the laws of the State of New York and -the intellectual property laws of the United States of America. No party -to this Agreement will bring a legal action under this Agreement more -than one year after the cause of action arose. Each party waives its -rights to a jury trial in any resulting litigation.

- - - - Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/GraphConverter.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/GraphConverter.java (revision 107e83a06604848b72d0e4cd9ae3bc84d786d0db) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/GraphConverter.java (revision 0) @@ -1,119 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical; - -import java.util.HashMap; -import java.util.Map; - -import de.cau.cs.kieler.core.alg.AbstractAlgorithm; -import de.cau.cs.kieler.core.kgraph.KEdge; -import de.cau.cs.kieler.core.kgraph.KNode; -import de.cau.cs.kieler.core.kgraph.KPort; -import de.cau.cs.kieler.kiml.klayoutdata.KShapeLayout; -import de.cau.cs.kieler.kiml.util.KimlUtil; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimEdge; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimGraph; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimNode; - -/** - * Class that converts a KGraph into a slim graph. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class GraphConverter extends AbstractAlgorithm { - - /** map of layout nodes and ports to KIELER nodes. */ - private Map nodeMap = new HashMap(); - - /** - * {@inheritDoc} - */ - @Override - public void reset() { - super.reset(); - nodeMap.clear(); - } - - /** - * Converts a given Ecore graph into a slim graph. Each node contains a - * reference to the corresponding layout node, and each edge contains a - * reference to the corresponding layout edge. - * - * @param parentNode parent node to be converted - * @param includePorts if true, the external ports of the parent node will - * also be added as nodes - * @return a graph which consists of the child nodes - */ - public KSlimGraph convertGraph(final KNode parentNode, final boolean includePorts) { - getMonitor().begin("Graph conversion", 1); - KSlimGraph slimGraph = new KSlimGraph(); - - // convert nodes - for (KNode child : parentNode.getChildren()) { - KShapeLayout nodeLayout = child.getData(KShapeLayout.class); - KSlimNode newNode = new KSlimNode(slimGraph, child); - newNode.setXpos(nodeLayout.getXpos()); - newNode.setYpos(nodeLayout.getYpos()); - nodeMap.put(child, newNode); - } - - // convert edges - for (KNode child : parentNode.getChildren()) { - for (KEdge layoutEdge : child.getOutgoingEdges()) { - KNode targetNode = layoutEdge.getTarget(); - if (targetNode.getParent() == child.getParent()) { - KSlimEdge newEdge = new KSlimEdge(slimGraph, nodeMap.get(child), nodeMap - .get(targetNode), layoutEdge); - newEdge.connectNodes(); - } - } - } - - if (includePorts) { - // convert external ports - for (KPort port : parentNode.getPorts()) { - KShapeLayout portLayout = port.getData(KShapeLayout.class); - KSlimNode newNode = new KSlimNode(slimGraph, port); - newNode.setXpos(portLayout.getXpos()); - newNode.setYpos(portLayout.getYpos()); - nodeMap.put(port, newNode); - } - - // convert edges to external ports - for (KPort port : parentNode.getPorts()) { - int flow = KimlUtil.calcFlow(port); - for (KEdge layoutEdge : port.getEdges()) { - KNode source = layoutEdge.getSource(); - KNode target = layoutEdge.getTarget(); - if (layoutEdge.getSourcePort() == port && target.getParent() == parentNode - && flow < 0) { - KSlimEdge newEdge = new KSlimEdge(slimGraph, nodeMap.get(port), nodeMap - .get(target), layoutEdge); - newEdge.connectNodes(); - } else if (layoutEdge.getTargetPort() == port && source.getParent() == parentNode - && flow > 0) { - KSlimEdge newEdge = new KSlimEdge(slimGraph, nodeMap.get(source), nodeMap - .get(port), layoutEdge); - newEdge.connectNodes(); - } - } - } - } - - getMonitor().done(); - return slimGraph; - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/HierarchicalDataflowLayoutProvider.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/HierarchicalDataflowLayoutProvider.java (revision caa3ca26cb6fca0f3f735cc068403582b354bc2c) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/HierarchicalDataflowLayoutProvider.java (revision 0) @@ -1,323 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2008 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical; - -import java.util.LinkedList; -import java.util.List; - -import de.cau.cs.kieler.core.IKielerPreferenceStore; -import de.cau.cs.kieler.core.alg.IKielerProgressMonitor; -import de.cau.cs.kieler.core.kgraph.KEdge; -import de.cau.cs.kieler.core.kgraph.KGraphData; -import de.cau.cs.kieler.core.kgraph.KNode; -import de.cau.cs.kieler.core.properties.IProperty; -import de.cau.cs.kieler.core.properties.Property; -import de.cau.cs.kieler.kiml.AbstractLayoutProvider; -import de.cau.cs.kieler.kiml.klayoutdata.KEdgeLayout; -import de.cau.cs.kieler.kiml.klayoutdata.KPoint; -import de.cau.cs.kieler.kiml.klayoutdata.KShapeLayout; -import de.cau.cs.kieler.kiml.options.Direction; -import de.cau.cs.kieler.kiml.options.LayoutOptions; -import de.cau.cs.kieler.kiml.util.KimlUtil; -import de.cau.cs.kieler.klodd.hierarchical.impl.BalancingLayerAssigner; -import de.cau.cs.kieler.klodd.hierarchical.impl.BalancingNodePlacer; -import de.cau.cs.kieler.klodd.hierarchical.impl.BarycenterCrossingReducer; -import de.cau.cs.kieler.klodd.hierarchical.impl.BasicNodePlacer; -import de.cau.cs.kieler.klodd.hierarchical.impl.InteractiveCrossingReducer; -import de.cau.cs.kieler.klodd.hierarchical.impl.LayerSweepCrossingReducer; -import de.cau.cs.kieler.klodd.hierarchical.impl.LongestPathLayerAssigner; -import de.cau.cs.kieler.klodd.hierarchical.impl.RectilinearEdgeRouter; -import de.cau.cs.kieler.klodd.hierarchical.impl.SortingLayerwiseEdgePlacer; -import de.cau.cs.kieler.klodd.hierarchical.impl.SortingNodewiseEdgePlacer; -import de.cau.cs.kieler.klodd.hierarchical.impl.ToponumLayerwiseEdgePlacer; -import de.cau.cs.kieler.klodd.hierarchical.modules.ICrossingReducer; -import de.cau.cs.kieler.klodd.hierarchical.modules.IEdgeRouter; -import de.cau.cs.kieler.klodd.hierarchical.modules.ILayerAssigner; -import de.cau.cs.kieler.klodd.hierarchical.modules.ILayerwiseEdgePlacer; -import de.cau.cs.kieler.klodd.hierarchical.modules.INodePlacer; -import de.cau.cs.kieler.klodd.hierarchical.modules.INodewiseEdgePlacer; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayeredGraph; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimEdge; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimGraph; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.alg.DFSCycleRemover; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.alg.GreedyCycleRemover; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.alg.ICycleRemover; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.alg.InteractiveCycleRemover; - -/** - * Layout provider for the KLoDD hierarchical dataflow diagram layouter. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class HierarchicalDataflowLayoutProvider extends AbstractLayoutProvider { - - /** default value for minimal distance. */ - public static final float DEF_MIN_DIST = 15.0f; - /** preference identifier for cycle remover module. */ - public static final String PREF_CYCLE_REM = "klodd.hierarchical.cycleRem"; - /** value for DFS cycle remover module. */ - public static final String VAL_DFS_CYCLE_REM = "dfs"; - /** value for greedy cycle remover module. */ - public static final String VAL_GREEDY_CYCLE_REM = "greedy"; - /** preference identifier for layer assignment module. */ - public static final String PREF_LAYER_ASS = "klodd.hierarchical.layerAss"; - /** value for longest path layer assignment module. */ - public static final String VAL_LONGP_LAYER_ASS = "longp"; - /** value for balancing layer assignment module. */ - public static final String VAL_BAL_LAYER_ASS = "bal"; - /** preference identifier for layerwise edge placement module. */ - public static final String PREF_LAYER_EDGEROUTER = "klodd.hierarchical.layerEdge"; - /** value for sorting layerwise edge placer module. */ - public static final String VAL_SORT_LAYER_EDGEROUTER = "sort"; - /** value for topological numbering layerwise edge placer module. */ - public static final String VAL_TOPO_LAYER_EDGEROUTER = "topo"; - /** preference identifier for the number of passes for crossing reduction. */ - public static final String PREF_CROSSRED_PASSES = "klodd.hierarchical.crossRedPasses"; - /** default value for the number of passes for crossing reduction. */ - public static final int DEF_CROSSRED_PASSES = 2; - /** preference identifier for the priority of node balancing over diagram size. */ - public static final String PREF_BALANCE_VS_SIZE = "klodd.hierarchical.balance"; - /** layout option identifier: level of interaction. */ - public static final String INTERACTIVE_ID = "de.cau.cs.kieler.klodd.interactive"; - /** level of interaction property. */ - public static final IProperty INTERACTIVE = new Property( - INTERACTIVE_ID, InteractionLevel.NONE); - - /** the preference store for this layouter. */ - private static IKielerPreferenceStore preferenceStore; - - /** - * Sets the preference store. - * - * @param thepreferenceStore the preference store to set - */ - public static void setPreferenceStore(final IKielerPreferenceStore thepreferenceStore) { - HierarchicalDataflowLayoutProvider.preferenceStore = thepreferenceStore; - } - - /** the graph converter module. */ - private GraphConverter graphConverter = new GraphConverter(); - /** the cycle remover module. */ - private ICycleRemover cycleRemover = null; - /** the layer assigner module. */ - private ILayerAssigner layerAssigner = null; - /** the crossing reducer module. */ - private ICrossingReducer crossingReducer = null; - /** the nodewise edge placer module. */ - private INodewiseEdgePlacer nodewiseEdgePlacer = null; - /** the node placer module. */ - private INodePlacer nodePlacer = null; - /** the layerwise edge placer module. */ - private ILayerwiseEdgePlacer layerwiseEdgePlacer = null; - /** the edge router module. */ - private IEdgeRouter edgeRouter = null; - - /** indicates whether node balance has priority over diagram size. */ - private boolean balanceOverSize; - - /** amount of work for a small task. */ - private static final int SMALL_TASK = 5; - /** amount of work for a large task. */ - private static final int LARGE_TASK = 15; - - /** - * {@inheritDoc} - */ - @Override - public void doLayout(final KNode layoutNode, final IKielerProgressMonitor progressMonitor) { - progressMonitor.begin("Hierarchical layout", - SMALL_TASK + SMALL_TASK + SMALL_TASK + LARGE_TASK + LARGE_TASK - + LARGE_TASK + LARGE_TASK); - // get the currently configured modules - KShapeLayout parentLayout = layoutNode.getData(KShapeLayout.class); - updateModules(parentLayout); - // set option for minimal object spacing - float objSpacing = parentLayout.getProperty(LayoutOptions.SPACING); - if (objSpacing < 0) { - objSpacing = DEF_MIN_DIST; - } - // set option for border spacing - float borderSpacing = parentLayout.getProperty(LayoutOptions.BORDER_SPACING); - if (borderSpacing < 0) { - borderSpacing = DEF_MIN_DIST; - } - - // perform some pre-processing - preProcess(layoutNode); - // create a slim graph for cycle removal - graphConverter.reset(progressMonitor.subTask(SMALL_TASK)); - KSlimGraph slimGraph = graphConverter.convertGraph(layoutNode, true); - // remove cycles in the input graph - cycleRemover.reset(progressMonitor.subTask(SMALL_TASK)); - cycleRemover.removeCycles(slimGraph); - // put each node into a layer and get a layered graph - layerAssigner.reset(progressMonitor.subTask(LARGE_TASK)); - LayeredGraph layeredGraph = layerAssigner.assignLayers(slimGraph, layoutNode, - objSpacing, balanceOverSize); - if (!layeredGraph.getLayers().isEmpty()) { - layeredGraph.createConnections(slimGraph); - // optimize the order of nodes in each layer - crossingReducer.reset(progressMonitor.subTask(LARGE_TASK)); - crossingReducer.reduceCrossings(layeredGraph); - // determine a placement for all edge endpoints - nodewiseEdgePlacer.reset(progressMonitor.subTask(LARGE_TASK)); - nodewiseEdgePlacer.placeEdges(layeredGraph); - // determine a crosswise placement for each node - nodePlacer.reset(progressMonitor.subTask(LARGE_TASK)); - nodePlacer.placeNodes(layeredGraph, objSpacing, borderSpacing, balanceOverSize); - // route edges between nodes - edgeRouter.reset(progressMonitor.subTask(LARGE_TASK)); - edgeRouter.routeEdges(layeredGraph, objSpacing, borderSpacing); - } - layeredGraph.applyLayout(); - restoreCycles(); - - progressMonitor.done(); - } - - /** - * Sets the internally used algorithm modules to the current configuration. - * - * @param parentLayout layout data of the parent node - */ - private void updateModules(final KShapeLayout parentLayout) { - InteractionLevel interactionLevel = parentLayout.getProperty(INTERACTIVE); - // choose cycle remover module - if (interactionLevel == InteractionLevel.CYCLES - || interactionLevel == InteractionLevel.LAYERS - || interactionLevel == InteractionLevel.FULL) { - if (!(cycleRemover instanceof InteractiveCycleRemover)) { - cycleRemover = new InteractiveCycleRemover(); - } - Direction layoutDirection = parentLayout.getProperty(LayoutOptions.DIRECTION); - ((InteractiveCycleRemover) cycleRemover).setVertical( - layoutDirection == Direction.DOWN); - } else if (preferenceStore != null - && preferenceStore.getString(PREF_CYCLE_REM).equals(VAL_DFS_CYCLE_REM)) { - if (!(cycleRemover instanceof DFSCycleRemover)) { - cycleRemover = new DFSCycleRemover(); - } - } else { - if (!(cycleRemover instanceof GreedyCycleRemover)) { - cycleRemover = new GreedyCycleRemover(); - } - } - - // choose layer assignment module - if (preferenceStore != null - && preferenceStore.getString(PREF_LAYER_ASS).equals(VAL_LONGP_LAYER_ASS)) { - if (!(layerAssigner instanceof LongestPathLayerAssigner)) { - layerAssigner = new LongestPathLayerAssigner(); - } - } else { - if (!(layerAssigner instanceof BalancingLayerAssigner)) { - layerAssigner = new BalancingLayerAssigner(new LongestPathLayerAssigner()); - } - } - - if (interactionLevel == InteractionLevel.ORDERING - || interactionLevel == InteractionLevel.FULL) { - if (!(crossingReducer instanceof InteractiveCrossingReducer)) { - crossingReducer = new InteractiveCrossingReducer(); - } - } else { - if (!(crossingReducer instanceof LayerSweepCrossingReducer)) { - crossingReducer = new LayerSweepCrossingReducer(new BarycenterCrossingReducer()); - } - int passes = DEF_CROSSRED_PASSES; - if (preferenceStore != null) { - int prefPasses = preferenceStore.getInt(PREF_CROSSRED_PASSES); - if (prefPasses > 0) { - passes = prefPasses; - } - } - ((LayerSweepCrossingReducer) crossingReducer).setPasses(passes); - } - - if (nodewiseEdgePlacer == null) { - nodewiseEdgePlacer = new SortingNodewiseEdgePlacer(); - } - if (nodePlacer == null) { - nodePlacer = new BalancingNodePlacer(new BasicNodePlacer()); - } - - // choose edge router module - if (preferenceStore != null - && preferenceStore.getString(PREF_LAYER_EDGEROUTER).equals(VAL_SORT_LAYER_EDGEROUTER)) { - if (!(layerwiseEdgePlacer instanceof SortingLayerwiseEdgePlacer)) { - layerwiseEdgePlacer = new SortingLayerwiseEdgePlacer(); - edgeRouter = new RectilinearEdgeRouter(layerwiseEdgePlacer); - } - } else { - if (!(layerwiseEdgePlacer instanceof ToponumLayerwiseEdgePlacer)) { - layerwiseEdgePlacer = new ToponumLayerwiseEdgePlacer(); - edgeRouter = new RectilinearEdgeRouter(layerwiseEdgePlacer); - } - } - - // set balance over size option - if (preferenceStore != null) { - balanceOverSize = preferenceStore.getBoolean(PREF_BALANCE_VS_SIZE); - } else { - balanceOverSize = true; - } - } - - /** - * Performs some pre-processing for the elements of the given parent node. - * - * @param parentNode parent layout node - */ - private void preProcess(final KNode parentNode) { - KGraphData parentLayout = parentNode.getData(KShapeLayout.class); - Direction layoutDirection = parentLayout.getProperty(LayoutOptions.DIRECTION); - - for (KNode node : parentNode.getChildren()) { - // fill port data for the child node - KimlUtil.fillPortInfo(node, layoutDirection); - - // set node size if not fixed - KimlUtil.resizeNode(node); - } - - // fill port data for the parent node - KimlUtil.fillPortInfo(parentNode, layoutDirection); - } - - /** - * Restores the edges that were reversed for cycle removal. - */ - private void restoreCycles() { - List reversedEdges = cycleRemover.getReversedEdges(); - for (KSlimEdge slimEdge : reversedEdges) { - KEdge layoutEdge = (KEdge) slimEdge.getObject(); - KEdgeLayout edgeLayout = layoutEdge.getData(KEdgeLayout.class); - // reverse bend points - List bendPoints = new LinkedList(); - for (KPoint point : edgeLayout.getBendPoints()) { - bendPoints.add(0, point); - } - edgeLayout.getBendPoints().clear(); - for (KPoint point : bendPoints) { - edgeLayout.getBendPoints().add(point); - } - // reverse source and target point - KPoint sourcePoint = edgeLayout.getSourcePoint(); - edgeLayout.setSourcePoint(edgeLayout.getTargetPoint()); - edgeLayout.setTargetPoint(sourcePoint); - } - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/InteractionLevel.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/InteractionLevel.java (revision 9126fc83fa322a590deb763fe9df86cc3f9a4128) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/InteractionLevel.java (revision 0) @@ -1,34 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2010 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical; - -/** - * Definition of possible interaction levels. - * - * @author msp - */ -public enum InteractionLevel { - - /** no user interaction. */ - NONE, - /** user positioning is considered for cycle breaking. */ - CYCLES, - /** user positioning is considered for cycle breaking and layering. */ - LAYERS, - /** user positioning is considered for node ordering. */ - ORDERING, - /** full user interaction. */ - FULL; - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/BalancingLayerAssigner.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/BalancingLayerAssigner.java (revision 239eb780788485f9211408ba8fbcc4c80d04aa0d) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/BalancingLayerAssigner.java (revision 0) @@ -1,168 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.impl; - -import java.util.ListIterator; - -import de.cau.cs.kieler.core.alg.AbstractAlgorithm; -import de.cau.cs.kieler.core.kgraph.KNode; -import de.cau.cs.kieler.kiml.klayoutdata.KShapeLayout; -import de.cau.cs.kieler.kiml.options.Direction; -import de.cau.cs.kieler.kiml.options.LayoutOptions; -import de.cau.cs.kieler.klodd.hierarchical.HierarchicalDataflowLayoutProvider; -import de.cau.cs.kieler.klodd.hierarchical.InteractionLevel; -import de.cau.cs.kieler.klodd.hierarchical.modules.ILayerAssigner; -import de.cau.cs.kieler.klodd.hierarchical.structures.Layer; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayerElement; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayeredGraph; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimGraph; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimNode; - -/** - * Layer assigner that balances the output of a basic layer assigner. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class BalancingLayerAssigner extends AbstractAlgorithm implements ILayerAssigner { - - /** the basic layer assigner instance. */ - private ILayerAssigner basicLayerAssigner; - - /** - * Creates a balancing layer assigner using a basic layer assigner. - * - * @param thebasicLayerAssigner basic layer assigner - */ - public BalancingLayerAssigner(final ILayerAssigner thebasicLayerAssigner) { - this.basicLayerAssigner = thebasicLayerAssigner; - } - - /** - * {@inheritDoc} - */ - public LayeredGraph assignLayers(final KSlimGraph graph, final KNode parentNode, - final float objSpacing, final boolean balanceOverSize) { - getMonitor().begin("Balancing layer assignment", 1); - basicLayerAssigner.reset(getMonitor().subTask(1)); - LayeredGraph layeredGraph = basicLayerAssigner.assignLayers(graph, parentNode, - objSpacing, balanceOverSize); - KShapeLayout parentLayout = parentNode.getData(KShapeLayout.class); - InteractionLevel interactionLevel = parentLayout.getProperty( - HierarchicalDataflowLayoutProvider.INTERACTIVE); - boolean interactive = interactionLevel == InteractionLevel.LAYERS - || interactionLevel == InteractionLevel.FULL; - Direction layoutDirection = parentLayout.getProperty(LayoutOptions.DIRECTION); - boolean vertical = layoutDirection == Direction.DOWN; - - // balance layer assignment of each element in the layering - if (layeredGraph.getLayers().size() >= 2) { - ListIterator layerIter = layeredGraph.getLayers().listIterator(1); - while (layerIter.hasNext()) { - Layer layer = layerIter.next(); - if (layer.getHeight() > 0) { - ListIterator elemIter = layer.getElements().listIterator(); - while (elemIter.hasNext()) { - balanceElement(layeredGraph, elemIter, objSpacing, - balanceOverSize, interactive, vertical); - } - } - } - } - - getMonitor().done(); - return layeredGraph; - } - - /** - * Balances the given element by finding a possibly better layer above the - * element. - * - * @param layeredGraph layered graph - * @param elemIter iterator whose next element shall be balanced - * @param objSpacing minimal distance between objects - * @param balanceOverSize indicates whether node balancing has priority over - * diagram size - * @param interactive if true, initial positioning is considered - * @param vertical if true, vertical layout is performed - */ - private void balanceElement(final LayeredGraph layeredGraph, - final ListIterator elemIter, final float objSpacing, - final boolean balanceOverSize, final boolean interactive, final boolean vertical) { - LayerElement element = elemIter.next(); - Layer currentLayer = element.getLayer(); - KSlimNode kNode = element.getKNode(); - int incoming = 0, outgoing = 0, minShiftRank = 0; - for (KSlimNode.IncEntry edgeEntry : kNode.getIncidence()) { - if (edgeEntry.getType() == KSlimNode.IncEntry.Type.OUT) { - outgoing++; - } else { - incoming++; - int shiftRank = layeredGraph.getLayerElement(edgeEntry.endpoint() - .getObject()).getLayer().getRank() + 1; - minShiftRank = Math.max(minShiftRank, shiftRank); - } - } - int layerOffset = layeredGraph.getLayers().get(0).getRank(); - if (interactive) { - if (minShiftRank - layerOffset < 0) { - minShiftRank = 1; - } - ListIterator layerIter = layeredGraph.getLayers().listIterator( - minShiftRank - layerOffset); - Layer layer = layerIter.next(); - while (layerIter.nextIndex() <= currentLayer.getRank() - layerOffset) { - Layer nextLayer = layerIter.next(); - boolean fits = true; - for (LayerElement nextElement : nextLayer.getElements()) { - KSlimNode nextKnode = nextElement.getKNode(); - if (!nextKnode.equals(kNode) - && (vertical && kNode.getYpos() > nextKnode.getYpos() - objSpacing / 2 - || !vertical && kNode.getXpos() > nextKnode.getXpos() - objSpacing / 2)) { - fits = false; - break; - } - } - if (fits) { - // move the current element to the new layer - elemIter.remove(); - element.setLayer(layer); - break; - } - layer = nextLayer; - } - } else if (minShiftRank > 0 && incoming >= outgoing) { - if (balanceOverSize) { - if (minShiftRank < currentLayer.getRank()) { - elemIter.remove(); - element.setLayer(layeredGraph.getLayers().get(minShiftRank - layerOffset)); - } - } else { - ListIterator layerIter = layeredGraph.getLayers().listIterator( - minShiftRank - layerOffset); - int currentSize = currentLayer.getElements().size(); - while (layerIter.nextIndex() < currentLayer.getRank() - layerOffset) { - Layer layer = layerIter.next(); - if (layer.getElements().size() <= currentSize) { - // move the current element to the new layer - elemIter.remove(); - element.setLayer(layer); - break; - } - } - } - } - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/BalancingNodePlacer.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/BalancingNodePlacer.java (revision 239eb780788485f9211408ba8fbcc4c80d04aa0d) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/BalancingNodePlacer.java (revision 0) @@ -1,267 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2008 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.impl; - -import java.util.ListIterator; - -import de.cau.cs.kieler.core.alg.AbstractAlgorithm; -import de.cau.cs.kieler.kiml.klayoutdata.KPoint; -import de.cau.cs.kieler.kiml.options.Direction; -import de.cau.cs.kieler.kiml.options.PortConstraints; -import de.cau.cs.kieler.klodd.hierarchical.modules.INodePlacer; -import de.cau.cs.kieler.klodd.hierarchical.structures.Layer; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayerConnection; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayerElement; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayeredGraph; -import de.cau.cs.kieler.klodd.hierarchical.structures.LinearSegment; - -/** - * Node placing algorithm that improves the overall balance of the graph after - * executing a basic node placer. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class BalancingNodePlacer extends AbstractAlgorithm implements INodePlacer { - - /** basic node placer that is executed before this algorithm begins. */ - private BasicNodePlacer basicNodePlacer; - /** minimal distance between two nodes or edges in each layer. */ - private float objSpacing; - /** maximal crosswise dimension of the layered graph. */ - private float maxWidth; - /** layout direction for this algorithm instance. */ - private Direction layoutDirection; - /** indicates whether node balancing has priority over diagram size. */ - private boolean balanceOverSize; - /** array of move requests for the linear segments. */ - private float[] moveRequests; - - /** - * Creates a balancing node placer using a basic node placer. The basic node - * placer is expected to create a layout where all layer elements are - * aligned to the top for horizontal layout or to the left for vertical - * layout. - * - * @param thebasicNodePlacer node placing algorithm that creates an initial - * unbalanced placement for each node - */ - public BalancingNodePlacer(final BasicNodePlacer thebasicNodePlacer) { - this.basicNodePlacer = thebasicNodePlacer; - } - - /** - * {@inheritDoc} - */ - public void placeNodes(final LayeredGraph layeredGraph, final float theobjSpacing, - final float borderSpacing, final boolean thebalanceOverSize) { - getMonitor().begin("Balancing node placement", 2); - - this.objSpacing = theobjSpacing; - this.layoutDirection = layeredGraph.getLayoutDirection(); - this.balanceOverSize = thebalanceOverSize; - // apply the basic node placement - basicNodePlacer.reset(getMonitor().subTask(1)); - basicNodePlacer.placeNodes(layeredGraph, theobjSpacing, borderSpacing, thebalanceOverSize); - int movableCount = basicNodePlacer.getMovableSegments().length; - - // create array of move requests - moveRequests = new float[movableCount]; - for (int i = 0; i < movableCount; i++) { - moveRequests[i] = Float.NaN; - } - // find the layer with the greatest crosswise dimension - maxWidth = 0.0f; - int referenceRank = 0; - for (Layer layer : layeredGraph.getLayers()) { - if (isMovable(layer) && layer.getCrosswiseDim() > maxWidth) { - maxWidth = layer.getCrosswiseDim(); - referenceRank = layer.getRank(); - } - } - ListIterator layerIter = layeredGraph.getLayers().listIterator(); - Layer layer; - do { - layer = layerIter.hasNext() ? layerIter.next() : null; - } while (layer != null && layer.getRank() <= referenceRank); - - // create move requests below the reference layer - while (layer != null) { - if (isMovable(layer)) { - createRequests(layer, true); - validateRequests(layer); - } - layer = layerIter.hasNext() ? layerIter.next() : null; - } - - // revalidate all requests below the reference layer - while (layerIter.hasPrevious()) { - layer = layerIter.previous(); - if (layer.getRank() <= referenceRank) { - break; - } - if (isMovable(layer)) { - validateRequests(layer); - } - } - - // create move requests above the reference layer - do { - if (isMovable(layer)) { - createRequests(layer, false); - validateRequests(layer); - } - layer = layerIter.hasPrevious() ? layerIter.previous() : null; - } while (layer != null); - - // revalidate all requests above the reference layer - while (layerIter.hasNext()) { - layer = layerIter.next(); - if (layer.getRank() > referenceRank) { - break; - } - if (isMovable(layer)) { - validateRequests(layer); - } - } - - // apply all move requests - for (LinearSegment linearSegment : basicNodePlacer.getMovableSegments()) { - float moveDelta = moveRequests[linearSegment.getRank()]; - if (!Float.isNaN(moveDelta)) { - for (LayerElement element : linearSegment.getElements()) { - KPoint pos = element.getPosition(); - if (layoutDirection == Direction.DOWN) { - pos.setX(pos.getX() + moveDelta); - } else { - pos.setY(pos.getY() + moveDelta); - } - } - } - } - - // update crosswise dimension for the whole graph - for (Layer layer2 : layeredGraph.getLayers()) { - LayerElement lastElem = layer2.getElements().get(layer2.getElements().size() - 1); - layer2.setCrosswiseDim(layoutDirection == Direction.DOWN - ? lastElem.getPosition().getX() : lastElem.getPosition().getY() - + lastElem.getTotalCrosswiseDim(objSpacing, false) + borderSpacing); - layeredGraph.setCrosswiseDim(Math.max(layeredGraph.getCrosswiseDim(), - layer2.getCrosswiseDim())); - } - - getMonitor().done(); - } - - /** - * Creates move requests for the elements of a given layer. - * - * @param layer layer to process - * @param forward if true, incoming connections are considered, else - * outgoing connections are considered - */ - private void createRequests(final Layer layer, final boolean forward) { - float lastRequest = 0.0f; - for (LayerElement element : layer.getElements()) { - if (Float.isNaN(moveRequests[element.getLinearSegment().getRank()])) { - // calculate preferred centered position as barycenter - float sum = 0.0f; - int edgeCount = 0; - for (LayerConnection connection : (forward - ? element.getIncomingConnections() : element.getOutgoingConnections())) { - sum += calcPosDelta(connection, forward); - edgeCount++; - } - if (edgeCount == 0) { - moveRequests[element.getLinearSegment().getRank()] = lastRequest; - } else { - float moveRequest = sum / edgeCount; - moveRequests[element.getLinearSegment().getRank()] = moveRequest; - lastRequest = moveRequest; - } - } - } - } - - /** - * Validate the requests of a layer. - * - * @param layer layer to process - */ - private void validateRequests(final Layer layer) { - ListIterator elemIter = layer.getElements().listIterator( - layer.getElements().size()); - float maxMove = Float.MAX_VALUE; - if (!balanceOverSize) { - maxMove = maxWidth - layer.getCrosswiseDim(); - } - while (elemIter.hasPrevious()) { - LayerElement element = elemIter.previous(); - float elemRequest = moveRequests[element.getLinearSegment().getRank()]; - elemRequest = elemRequest < 0.0f ? 0.0f : elemRequest; - Float spacing = basicNodePlacer.getElementSpacing().get(element); - if (spacing == null) { - maxMove = Math.min(elemRequest, maxMove); - } else { - maxMove = Math.min(elemRequest, maxMove + spacing.floatValue()); - } - moveRequests[element.getLinearSegment().getRank()] = maxMove; - } - } - - /** - * Determines the difference between the endpoint positions of the source - * and target of a connection. - * - * @param connection connection to process - * @param forward if true the source position is taken positively, else - * negatively - * @return position difference - */ - private float calcPosDelta(final LayerConnection connection, final boolean forward) { - float sourcePos = connection.calcSourcePos(objSpacing); - float targetPos = connection.calcTargetPos(objSpacing); - - // determine position delta, considering previous move requests - if (forward) { - float sourceRequest = moveRequests[connection.getSourceElement() - .getLinearSegment().getRank()]; - if (Float.isNaN(sourceRequest)) { - return sourcePos - targetPos; - } else { - return sourcePos + sourceRequest - targetPos; - } - } else { - float targetRequest = moveRequests[connection.getTargetElement() - .getLinearSegment().getRank()]; - if (Float.isNaN(targetRequest)) { - return targetPos - sourcePos; - } else { - return targetPos + targetRequest - sourcePos; - } - } - } - - /** - * Returns whether a given layer is movable or fixed. - * - * @param layer the layer - * @return true if the layer is movable - */ - private boolean isMovable(final Layer layer) { - return !(layer.getLayeredGraph().getExternalPortConstraints() - == PortConstraints.FIXED_POS && (layer.getRank() == 0 || layer.getHeight() == 0)); - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/BarycenterCrossingReducer.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/BarycenterCrossingReducer.java (revision 795a67e93d7a326b2dd70d94f21016af5b83ea11) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/BarycenterCrossingReducer.java (revision 0) @@ -1,239 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2008 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.impl; - -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; - -import de.cau.cs.kieler.core.alg.AbstractAlgorithm; -import de.cau.cs.kieler.core.kgraph.KPort; -import de.cau.cs.kieler.kiml.options.PortConstraints; -import de.cau.cs.kieler.klodd.hierarchical.modules.ISingleLayerCrossingReducer; -import de.cau.cs.kieler.klodd.hierarchical.structures.Layer; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayerElement; - -/** - * Implementation of the barycenter method for the 2-layer crossing reduction - * problem. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class BarycenterCrossingReducer extends AbstractAlgorithm implements ISingleLayerCrossingReducer { - - /** - * number of surrounding ranks to consider for elements with undefined - * abstract rank. - */ - private static final int RANK_AVG_RADIUS = 1; - - /** - * {@inheritDoc} - */ - public void reduceCrossings(final Layer layer, final boolean forward) { - getMonitor().begin("Barycenter method (layer " + layer.getRank() - + (forward ? ", forward)" : ", backwards)"), 1); - - double[] abstractRanks = new double[layer.getElements().size()]; - int elemIndex = 0; - for (LayerElement element : layer.getElements()) { - PortConstraints portConstraints = element.getPortConstraints(); - if (portConstraints == PortConstraints.FIXED_SIDE - || portConstraints == PortConstraints.FREE) { - // ports are not fixed, find an order for the ports - Map> portRanks = element.getConnectionRanksByPort(forward); - Map abstractPortRanks = new HashMap(); - List ports = new LinkedList(portRanks.keySet()); - double sum = 0.0; - ListIterator portsIter = ports.listIterator(); - while (portsIter.hasNext()) { - KPort port = portsIter.next(); - List rankList = portRanks.get(port); - double barycenter = calcBarycenter(rankList); - if (barycenter < 0.0) { - portsIter.remove(); - } else { - sum += barycenter; - abstractPortRanks.put(port, Double.valueOf(barycenter)); - } - } - if (ports.isEmpty()) { - // elements with no connections should stay where they are - abstractRanks[elemIndex] = -1.0; - } else { - element.sortPorts(abstractPortRanks, !forward); - abstractRanks[elemIndex] = sum / ports.size(); - } - } else { - // the ports of the current element are fixed, - // or there are no port constraints - List rankList = element.getConnectionRanks(forward); - abstractRanks[elemIndex] = calcBarycenter(rankList); - } - elemIndex++; - } - sortAbstract(layer, abstractRanks); - - getMonitor().done(); - } - - /** - * {@inheritDoc} - */ - public void reduceCrossings(final Layer layer) { - getMonitor().begin("Barycenter method", 1); - - double[] abstractRanks = new double[layer.getElements().size()]; - int elemIndex = 0; - for (LayerElement element : layer.getElements()) { - PortConstraints portConstraints = element.getPortConstraints(); - if (portConstraints == PortConstraints.FIXED_SIDE - || portConstraints == PortConstraints.FREE) { - // ports are not fixed, find an order for the ports - Map> forwardRanks = element.getConnectionRanksByPort(true); - Map> backwardsRanks = element.getConnectionRanksByPort(false); - Map abstractForward = new HashMap(); - Map abstractBackwards = new HashMap(); - List ports = new LinkedList(forwardRanks.keySet()); - double sum = 0.0; - ListIterator portsIter = ports.listIterator(); - while (portsIter.hasNext()) { - KPort port = portsIter.next(); - double bary1 = calcBarycenter(forwardRanks.get(port)); - double bary2 = calcBarycenter(backwardsRanks.get(port)); - double barycenter = mergeBarycenters(bary1, bary2); - if (barycenter < 0.0) { - portsIter.remove(); - } else { - sum += barycenter; - if (bary1 >= 0.0) { - abstractForward.put(port, Double.valueOf(bary1)); - } - if (bary2 >= 0.0) { - abstractBackwards.put(port, Double.valueOf(bary2)); - } - } - } - if (ports.isEmpty()) { - // elements with no connections should stay where they are - abstractRanks[elemIndex] = -1.0; - } else { - element.sortPorts(abstractBackwards, abstractForward); - abstractRanks[elemIndex] = sum / ports.size(); - } - } else { - // the ports of the current element are fixed, - // or there are no port constraints - double bary1 = calcBarycenter(element.getConnectionRanks(true)); - double bary2 = calcBarycenter(element.getConnectionRanks(false)); - abstractRanks[elemIndex] = mergeBarycenters(bary1, bary2); - } - elemIndex++; - } - sortAbstract(layer, abstractRanks); - - getMonitor().done(); - } - - /** - * Calculates the barycenter of a list of ranks. - * - * @param ranks list of ranks - * @return barycenter value - */ - private double calcBarycenter(final List ranks) { - if (ranks.isEmpty()) { - return -1.0; - } else { - int rankSum = 0; - for (int rank : ranks) { - rankSum += rank; - } - return (double) rankSum / ranks.size(); - } - } - - /** - * Merges two barycenter values, considering special cases. - * - * @param b1 first value - * @param b2 second value - * @return merged barycenter value - */ - private double mergeBarycenters(final double b1, final double b2) { - if (b1 < 0.0 && b2 < 0.0) { - return -1.0; - } else if (b1 < 0.0) { - return b2; - } else if (b2 < 0.0) { - return b1; - } else { - return (b1 + b2) / 2; - } - } - - /** - * Sorts the elements in the given layer and assigns them new rank values - * based on a map of abstract ranks. The algorithm tries to put elements - * with abstract rank smaller than zero near their previous position. - * - * @param layer layer to sort - * @param abstractRanks array of abstract ranks used as base for sorting - */ - private void sortAbstract(final Layer layer, final double[] abstractRanks) { - List elements = layer.getElements(); - // determine placements for elements with no abstract rank - final double[] filteredRanks = new double[elements.size()]; - int index = 0; - double lastRank = 0.0; - for (LayerElement element : elements) { - double arank = abstractRanks[index]; - if (arank < 0.0) { - int definedRanks = 0; - double sum = 0.0; - for (int i = index - RANK_AVG_RADIUS; i <= index + RANK_AVG_RADIUS; i++) { - if (i >= 0 && i < abstractRanks.length && abstractRanks[i] >= 0.0) { - sum += abstractRanks[i]; - definedRanks++; - } - } - if (definedRanks > 0) { - filteredRanks[index] = sum / definedRanks; - } else { - filteredRanks[index] = lastRank; - } - } else { - filteredRanks[index] = arank; - lastRank = arank; - } - element.setRank(index++); - } - - // sort all elements by the filtered ranks - Collections.sort(elements, new Comparator() { - public int compare(final LayerElement elem1, final LayerElement elem2) { - return Double.compare(filteredRanks[elem1.getRank()], filteredRanks[elem2.getRank()]); - } - }); - - // calculate concrete rank values - layer.calcElemRanks(); - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/BasicNodePlacer.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/BasicNodePlacer.java (revision 239eb780788485f9211408ba8fbcc4c80d04aa0d) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/BasicNodePlacer.java (revision 0) @@ -1,282 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2008 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.impl; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import de.cau.cs.kieler.core.alg.AbstractAlgorithm; -import de.cau.cs.kieler.core.kgraph.KPort; -import de.cau.cs.kieler.kiml.klayoutdata.KPoint; -import de.cau.cs.kieler.kiml.klayoutdata.KShapeLayout; -import de.cau.cs.kieler.kiml.options.Direction; -import de.cau.cs.kieler.kiml.options.LayoutOptions; -import de.cau.cs.kieler.kiml.options.PortConstraints; -import de.cau.cs.kieler.kiml.options.PortSide; -import de.cau.cs.kieler.klodd.hierarchical.modules.INodePlacer; -import de.cau.cs.kieler.klodd.hierarchical.structures.Layer; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayerElement; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayeredGraph; -import de.cau.cs.kieler.klodd.hierarchical.structures.LinearSegment; - -/** - * Node placing algorithm that orders all linear segments and creates an - * unbalanced placement. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class BasicNodePlacer extends AbstractAlgorithm implements INodePlacer { - - /** factor for the actual distance between nodes. */ - private static final float DIST_FACTOR = 1.37f; - - /** minimal distance between two nodes or edges in each layer. */ - private float objSpacing; - /** spacing to the border. */ - private float borderSpacing; - /** layout direction for this algorithm instance. */ - private Direction layoutDirection; - /** array of sorted segments. */ - private LinearSegment[] sortedSegments = null; - /** amount of available spacing for each layer element. */ - private Map spacingMap = new HashMap(); - /** the last element that was processed in each layer. */ - private LayerElement[] lastElements; - - /** - * {@inheritDoc} - */ - @Override - public void reset() { - super.reset(); - sortedSegments = null; - spacingMap.clear(); - } - - /** - * {@inheritDoc} - */ - public void placeNodes(final LayeredGraph layeredGraph, final float theobjSpacing, - final float theborderSpacing, final boolean balanceOverSize) { - getMonitor().begin("Basic node placement", 1); - - this.objSpacing = theobjSpacing; - this.borderSpacing = theborderSpacing; - this.layoutDirection = layeredGraph.getLayoutDirection(); - this.lastElements = new LayerElement[layeredGraph.getLayers().size() - + layeredGraph.getLayers().get(0).getRank()]; - - // sort the linear segments of the layered graph - sortedSegments = sortLinearSegments(layeredGraph); - // create an unbalanced placement from the sorted segments - createUnbalancedPlacement(sortedSegments); - - // process external ports - Layer externalLayer = layeredGraph.getLayers().get(0); - if (externalLayer.getRank() == 0) { - processExternalLayer(externalLayer); - } - externalLayer = layeredGraph.getLayers().get(layeredGraph.getLayers().size() - 1); - if (externalLayer.getHeight() == 0) { - processExternalLayer(externalLayer); - } - - // set the proper crosswise dimension for the whole graph - for (Layer layer : layeredGraph.getLayers()) { - layer.setCrosswiseDim(layer.getCrosswiseDim() + theborderSpacing); - layeredGraph.setCrosswiseDim(Math.max(layeredGraph.getCrosswiseDim(), - layer.getCrosswiseDim())); - } - - getMonitor().done(); - } - - /** - * Gets the array of movable linear segments. This excludes the external - * ports if their position is to be held fixed. - * - * @return movable linear segments - */ - public LinearSegment[] getMovableSegments() { - return sortedSegments; - } - - /** - * Gets a map for the amount of spacing available for each layer element. - * The last element of each layer is not stored in this map. - * - * @return spacing map - */ - public Map getElementSpacing() { - return spacingMap; - } - - /** - * Sorts the linear segments of the given layered graph by finding a - * topological ordering in the corresponding segment ordering graph. - * - * @param layeredGraph layered graph to process - * @return a sorted array of linear segments - */ - @SuppressWarnings("unchecked") - private LinearSegment[] sortLinearSegments(final LayeredGraph layeredGraph) { - // create and initialize segment ordering graph - LinearSegment[] linearSegments; - if (layeredGraph.getExternalPortConstraints() == PortConstraints.FIXED_POS) { - List filteredSegments = new LinkedList(); - for (LinearSegment segment : layeredGraph.getLinearSegments()) { - if (segment.getElements().size() == 1) { - Layer layer = segment.getElements().get(0).getLayer(); - if (layer.getRank() != 0 && layer.getHeight() != 0) { - filteredSegments.add(segment); - } - } else { - filteredSegments.add(segment); - } - } - linearSegments = filteredSegments.toArray(new LinearSegment[0]); - } else { - linearSegments = layeredGraph.getLinearSegments().toArray(new LinearSegment[0]); - } - List[] outgoing = new List[linearSegments.length]; - int[] incomingCount = new int[linearSegments.length]; - int[] newRanks = new int[linearSegments.length]; - for (int i = 0; i < linearSegments.length; i++) { - linearSegments[i].setRank(i); - outgoing[i] = new LinkedList(); - incomingCount[i] = 0; - } - - // create edges in the segment ordering graph - for (Layer layer : layeredGraph.getLayers()) { - if (!(layeredGraph.getExternalPortConstraints() == PortConstraints.FIXED_POS - && (layer.getRank() == 0 || layer.getHeight() == 0))) { - Iterator elemIter = layer.getElements().iterator(); - LayerElement elem1 = elemIter.next(); - while (elemIter.hasNext()) { - LayerElement elem2 = elemIter.next(); - outgoing[elem1.getLinearSegment().getRank()].add(elem2.getLinearSegment()); - incomingCount[elem2.getLinearSegment().getRank()]++; - elem1 = elem2; - } - } - } - - // find a topological ordering of the segment ordering graph - int nextRank = 0; - List noIncoming = new LinkedList(); - for (int i = 0; i < linearSegments.length; i++) { - if (incomingCount[i] == 0) { - noIncoming.add(linearSegments[i]); - } - } - while (!noIncoming.isEmpty()) { - LinearSegment segment = noIncoming.remove(0); - newRanks[segment.getRank()] = nextRank++; - while (!outgoing[segment.getRank()].isEmpty()) { - LinearSegment target = outgoing[segment.getRank()].remove(0); - incomingCount[target.getRank()]--; - if (incomingCount[target.getRank()] == 0) { - noIncoming.add(target); - } - } - } - - // apply the new ordering to the array of linear segments - for (int i = 0; i < linearSegments.length; i++) { - assert outgoing[i].isEmpty(); - linearSegments[i].setRank(newRanks[i]); - } - Arrays.sort(linearSegments); - return linearSegments; - } - - /** - * Creates an unbalanced placement for the input graph. - * - * @param thesortedSegments array of sorted linear segments - */ - private void createUnbalancedPlacement(final LinearSegment[] thesortedSegments) { - for (LinearSegment segment : thesortedSegments) { - // determine the leftmost / uppermost placement for the linear segment - float leftmostPlace = 0.0f; - for (LayerElement element : segment.getElements()) { - leftmostPlace = Math.max(leftmostPlace, element.getLayer().getCrosswiseDim()); - } - // apply the leftmost / uppermost placement to all elements - float newPos = leftmostPlace < borderSpacing ? borderSpacing - : leftmostPlace + DIST_FACTOR * objSpacing; - for (LayerElement element : segment.getElements()) { - Layer layer = element.getLayer(); - if (lastElements[layer.getRank()] != null) { - spacingMap.put(lastElements[layer.getRank()], Float.valueOf(leftmostPlace - - layer.getCrosswiseDim())); - } - float totalCrosswiseDim = element.getTotalCrosswiseDim(objSpacing, true); - element.setCrosswisePos(newPos, objSpacing); - layer.setCrosswiseDim(newPos + totalCrosswiseDim); - layer.setLengthwiseDim(Math.max(layer.getLengthwiseDim(), - element.getTotalLengthwiseDim(objSpacing))); - lastElements[layer.getRank()] = element; - } - } - } - - /** - * Adjusts the size properties of a layer that contains only external ports. - * - * @param layer layer with external ports - */ - private void processExternalLayer(final Layer layer) { - LayeredGraph layeredGraph = layer.getLayeredGraph(); - if (layeredGraph.getExternalPortConstraints() == PortConstraints.FIXED_POS) { - // process fixed external layer - for (LayerElement element : layer.getElements()) { - KPort port = (KPort) element.getElemObj(); - KShapeLayout portLayout = port.getData(KShapeLayout.class); - PortSide placement = portLayout.getProperty(LayoutOptions.PORT_SIDE); - KPoint position = element.getPosition(); - position.setX(portLayout.getXpos()); - position.setY(portLayout.getYpos()); - if (layoutDirection == Direction.DOWN) { - layer.setLengthwiseDim(Math.max(layer.getLengthwiseDim(), element.getRealHeight())); - if (placement != PortSide.EAST && placement != PortSide.WEST) { - layer.setCrosswiseDim(Math.max(layer.getCrosswiseDim(), - position.getX() + element.getRealWidth())); - } - if (placement != PortSide.NORTH && placement != PortSide.SOUTH) { - layeredGraph.setLengthwiseDim(Math.max(layeredGraph.getLengthwiseDim(), - position.getY())); - } - } else { - layer.setLengthwiseDim(Math.max(layer.getLengthwiseDim(), element.getRealWidth())); - if (placement != PortSide.NORTH && placement != PortSide.SOUTH) { - layer.setCrosswiseDim(Math.max(layer.getCrosswiseDim(), - position.getY() + element.getRealHeight())); - } - if (placement != PortSide.EAST && placement != PortSide.WEST) { - layeredGraph.setLengthwiseDim(Math.max(layeredGraph.getLengthwiseDim(), - position.getX())); - } - } - } - } - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/InteractiveCrossingReducer.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/InteractiveCrossingReducer.java (revision 239eb780788485f9211408ba8fbcc4c80d04aa0d) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/InteractiveCrossingReducer.java (revision 0) @@ -1,108 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2010 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.impl; - -import java.util.Collections; -import java.util.Comparator; - -import de.cau.cs.kieler.core.alg.AbstractAlgorithm; -import de.cau.cs.kieler.core.kgraph.KEdge; -import de.cau.cs.kieler.kiml.klayoutdata.KEdgeLayout; -import de.cau.cs.kieler.kiml.klayoutdata.KPoint; -import de.cau.cs.kieler.kiml.options.Direction; -import de.cau.cs.kieler.klodd.hierarchical.modules.ICrossingReducer; -import de.cau.cs.kieler.klodd.hierarchical.structures.Layer; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayerElement; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayeredGraph; - -/** - * - * @author msp - */ -public class InteractiveCrossingReducer extends AbstractAlgorithm implements ICrossingReducer { - - /** - * {@inheritDoc} - */ - public void reduceCrossings(final LayeredGraph layeredGraph) { - getMonitor().begin("Interactive crossing reduction", 1); - - final Direction layoutDirection = layeredGraph.getLayoutDirection(); - for (Layer layer : layeredGraph.getLayers()) { - // calculate lengthwise layer position - float lengthSum = 0.0f; - int count = 0; - for (LayerElement element : layer.getElements()) { - if (element.getKNode() != null) { - count++; - if (layoutDirection == Direction.DOWN) { - lengthSum += element.getKNode().getYpos(); - } else { - lengthSum += element.getKNode().getXpos(); - } - } - } - final float lengthPos = lengthSum / count; - - // sort all elements by their relative positions - Collections.sort(layer.getElements(), new Comparator() { - public int compare(final LayerElement elem1, final LayerElement elem2) { - return Float.compare(getCompareValue(elem1, layoutDirection, lengthPos), - getCompareValue(elem2, layoutDirection, lengthPos)); - } - }); - - // calculate concrete rank values - layer.calcElemRanks(); - } - - getMonitor().done(); - } - - private float getCompareValue(final LayerElement element, - final Direction layoutDirection, final float lengthPos) { - if (element.getKNode() != null) { - // process a node or external port - if (layoutDirection == Direction.DOWN) { - return element.getKNode().getXpos(); - } else { - return element.getKNode().getYpos(); - } - } else { - // process an edge - KEdge edge = (KEdge) element.getElemObj(); - KEdgeLayout edgeLayout = edge.getData(KEdgeLayout.class); - if (layoutDirection == Direction.DOWN) { - float currVal = edgeLayout.getSourcePoint().getX(); - for (KPoint bendPoint : edgeLayout.getBendPoints()) { - if (bendPoint.getY() > lengthPos) { - break; - } - currVal = bendPoint.getX(); - } - return currVal; - } else { - float currVal = edgeLayout.getSourcePoint().getY(); - for (KPoint bendPoint : edgeLayout.getBendPoints()) { - if (bendPoint.getX() > lengthPos) { - break; - } - currVal = bendPoint.getY(); - } - return currVal; - } - } - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/LayerSweepCrossingReducer.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/LayerSweepCrossingReducer.java (revision 795a67e93d7a326b2dd70d94f21016af5b83ea11) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/LayerSweepCrossingReducer.java (revision 0) @@ -1,145 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2008 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.impl; - -import java.util.ListIterator; - -import de.cau.cs.kieler.core.alg.AbstractAlgorithm; -import de.cau.cs.kieler.kiml.options.PortConstraints; -import de.cau.cs.kieler.klodd.hierarchical.modules.ICrossingReducer; -import de.cau.cs.kieler.klodd.hierarchical.modules.ISingleLayerCrossingReducer; -import de.cau.cs.kieler.klodd.hierarchical.structures.Layer; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayerElement; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayeredGraph; - -/** - * Implementation of a crossing reducer that performs a layer-by-layer sweep - * with a 2-layer crossing reducer. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class LayerSweepCrossingReducer extends AbstractAlgorithm implements ICrossingReducer { - - /** the algorithm used to reduce crossings between two or three layers. */ - private ISingleLayerCrossingReducer layerReducer; - /** number of passes for crossing reduction. */ - private int passes = 1; - - /** - * Creates a layer-by-layer sweep crossing reducer with given single layer - * crossing reducer. - * - * @param thelayerReducer the single layer crossing reducer - */ - public LayerSweepCrossingReducer(final ISingleLayerCrossingReducer thelayerReducer) { - this.layerReducer = thelayerReducer; - } - - /** - * Sets the number of passes for crossing reduction. - * - * @param thepasses number of passes - */ - public void setPasses(final int thepasses) { - if (thepasses >= 1) { - this.passes = thepasses; - } - } - - /** - * {@inheritDoc} - */ - public void reduceCrossings(final LayeredGraph layeredGraph) { - int layerCount = layeredGraph.getLayers().size(); - int firstLayerIx = 0, lastLayerIx = layerCount - 1; - getMonitor().begin("Crossing reduction", passes * 2 * (layerCount - 1)); - PortConstraints externalConstraints = layeredGraph.getExternalPortConstraints(); - - Layer firstLayer = layeredGraph.getLayers().get(firstLayerIx); - Layer lastLayer = layeredGraph.getLayers().get(lastLayerIx); - if (externalConstraints != PortConstraints.FREE) { - // sort input and output ports by their relative position - if (firstLayer.getRank() == 0) { - firstLayer.sortByPorts(false); - if (externalConstraints != PortConstraints.FIXED_SIDE) { - firstLayerIx += 2; - } - } - - if (lastLayer.getHeight() == 0) { - lastLayer.sortByPorts(false); - if (externalConstraints != PortConstraints.FIXED_SIDE) { - lastLayerIx -= 2; - } - } - } - - for (int i = 0; i < passes; i++) { - // process all but the port layers and the last layer - ListIterator layerIter = layeredGraph.getLayers().listIterator(1); - while (layerIter.nextIndex() <= lastLayerIx) { - layerReducer.reset(getMonitor().subTask(1)); - layerReducer.reduceCrossings(layerIter.next(), true); - } - - if (lastLayerIx < layerCount - 1) { - // order the last layer by the preceding layer and the output - // ports layer - layerReducer.reset(getMonitor().subTask(1)); - layerReducer.reduceCrossings(layerIter.next()); - } else { - if (externalConstraints == PortConstraints.FIXED_SIDE && lastLayer.getHeight() == 0) { - lastLayer.sortByPorts(true); - } - layerIter.previous(); - } - - // clear port ranks in the layered graph - for (Layer layer : layeredGraph.getLayers()) { - for (LayerElement element : layer.getElements()) { - element.clearPortRanks(); - } - } - - // process all but the port layers and the first layer again - while (layerIter.previousIndex() >= firstLayerIx) { - layerReducer.reset(getMonitor().subTask(1)); - layerReducer.reduceCrossings(layerIter.previous(), false); - } - - if (firstLayerIx > 0) { - // order the first layer by the subsequent layer and the input - // ports layer - layerReducer.reset(getMonitor().subTask(1)); - layerReducer.reduceCrossings(layerIter.previous()); - } else { - if (externalConstraints == PortConstraints.FIXED_SIDE && firstLayer.getRank() == 0) { - firstLayer.sortByPorts(true); - } - layerIter.next(); - } - - // clear port ranks in the layered graph - for (Layer layer : layeredGraph.getLayers()) { - for (LayerElement element : layer.getElements()) { - element.clearPortRanks(); - } - } - } - - getMonitor().done(); - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/LongestPathLayerAssigner.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/LongestPathLayerAssigner.java (revision 56d2d14998d7df2d292e7a859b27bb68ff23e805) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/LongestPathLayerAssigner.java (revision 0) @@ -1,121 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2008 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.impl; - -import java.util.ListIterator; - -import de.cau.cs.kieler.core.alg.AbstractAlgorithm; -import de.cau.cs.kieler.core.kgraph.KGraphElement; -import de.cau.cs.kieler.core.kgraph.KNode; -import de.cau.cs.kieler.core.kgraph.KPort; -import de.cau.cs.kieler.kiml.util.KimlUtil; -import de.cau.cs.kieler.klodd.hierarchical.modules.ILayerAssigner; -import de.cau.cs.kieler.klodd.hierarchical.structures.Layer; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayerElement; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayeredGraph; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimGraph; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimNode; - -/** - * Layer assigner working with the longest path layering algorithm. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class LongestPathLayerAssigner extends AbstractAlgorithm implements ILayerAssigner { - - /** the layered graph that is created by the layer assigner. */ - private LayeredGraph layeredGraph = null; - - /** - * {@inheritDoc} - */ - @Override - public void reset() { - super.reset(); - layeredGraph = null; - } - - /** - * {@inheritDoc} - */ - public LayeredGraph assignLayers(final KSlimGraph slimGraph, final KNode parentNode, - final float objSpacing, final boolean balanceOverSize) { - getMonitor().begin("Longest path layering", 1); - layeredGraph = new LayeredGraph(parentNode); - - // process child nodes - for (KSlimNode node : slimGraph.getNodes()) { - visit(node); - } - - // fill rank information for all layers - ListIterator layerIter = layeredGraph.getLayers().listIterator(); - if (layerIter.hasNext()) { - Layer currentLayer = layerIter.next(); - int rank = currentLayer.getRank(); - if (rank == Layer.UNDEF_RANK) { - rank = 1; - currentLayer.setRank(rank); - } - while (layerIter.hasNext()) { - Layer nextLayer = layerIter.next(); - nextLayer.setRank(++rank); - currentLayer.setNext(nextLayer); - currentLayer = nextLayer; - } - } - - getMonitor().done(); - return layeredGraph; - } - - /** - * Visit a node: if not already visited, find the longest path to a sink. - * - * @param node node to visit - * @return height of the given node in the layered graph - */ - private int visit(final KSlimNode node) { - LayerElement layerElement = layeredGraph.getLayerElement(node.getObject()); - if (layerElement != null) { - // the node was already visited - return layerElement.getLayer().getHeight(); - } else if (node.getObject() instanceof KPort) { - KPort port = (KPort) node.getObject(); - if (KimlUtil.calcFlow(port) < 0) { - layeredGraph.putFront(port, 0, node); - return Layer.UNDEF_HEIGHT; - } else { - layeredGraph.putBack(port, 0, node); - return 0; - } - } else { - int maxHeight = 1; - for (KSlimNode.IncEntry edgeEntry : node.getIncidence()) { - if (edgeEntry.getType() == KSlimNode.IncEntry.Type.OUT) { - KSlimNode targetNode = edgeEntry.getEdge().getTarget(); - // do not follow loops over a single node - if (targetNode.getId() != node.getId()) { - int height = visit(targetNode) + 1; - maxHeight = Math.max(height, maxHeight); - } - } - } - layeredGraph.putBack((KGraphElement) node.getObject(), maxHeight, node); - return maxHeight; - } - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/RectilinearEdgeRouter.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/RectilinearEdgeRouter.java (revision 239eb780788485f9211408ba8fbcc4c80d04aa0d) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/RectilinearEdgeRouter.java (revision 0) @@ -1,786 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2008 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.impl; - -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; - -import de.cau.cs.kieler.core.alg.AbstractAlgorithm; -import de.cau.cs.kieler.core.kgraph.KPort; -import de.cau.cs.kieler.kiml.klayoutdata.KLayoutDataFactory; -import de.cau.cs.kieler.kiml.klayoutdata.KPoint; -import de.cau.cs.kieler.kiml.klayoutdata.KShapeLayout; -import de.cau.cs.kieler.kiml.options.Direction; -import de.cau.cs.kieler.kiml.options.LayoutOptions; -import de.cau.cs.kieler.kiml.options.PortConstraints; -import de.cau.cs.kieler.kiml.options.PortSide; -import de.cau.cs.kieler.kiml.util.KimlUtil; -import de.cau.cs.kieler.klodd.hierarchical.modules.IEdgeRouter; -import de.cau.cs.kieler.klodd.hierarchical.modules.ILayerwiseEdgePlacer; -import de.cau.cs.kieler.klodd.hierarchical.structures.ElementLoop; -import de.cau.cs.kieler.klodd.hierarchical.structures.Layer; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayerConnection; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayerElement; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayeredGraph; -import de.cau.cs.kieler.klodd.hierarchical.structures.RoutingSlot; - -/** - * Edge routing algorithm that makes rectilinear edges. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class RectilinearEdgeRouter extends AbstractAlgorithm implements IEdgeRouter { - - /** - * Enumeration for types of routing of connections to or from external ports - * of a layered graph. - */ - private enum ExternalRouting { - NORMAL, FIRST, LAST, AROUND - } - - /** layerwise edge placer used to route layer connections. */ - private ILayerwiseEdgePlacer layerwiseEdgePlacer; - /** minimal distance between elements of the layered graph. */ - private float objSpacing; - /** spacing to the border. */ - private float borderSpacing; - /** lengthwise position of the currently processed layer. */ - private float layerPos; - /** maximal crosswise layout position of routed edges to external ports. */ - private float maxCrosswisePos; - /** maximal lengthwise layout position to be added to the total size. */ - private float maxLengthwiseAddPos; - - /** - * Creates a rectilinear edge router using a layerwise edge placer. - * - * @param thelayerwiseEdgePlacer layerwise edge placer used to route layer - * connections - */ - public RectilinearEdgeRouter(final ILayerwiseEdgePlacer thelayerwiseEdgePlacer) { - this.layerwiseEdgePlacer = thelayerwiseEdgePlacer; - } - - /** - * {@inheritDoc} - */ - public void routeEdges(final LayeredGraph layeredGraph, final float theobjSpacing, - final float theborderSpacing) { - getMonitor().begin("Rectilinear edge routing", layeredGraph.getLayers().size() - 1); - - this.objSpacing = theobjSpacing; - this.borderSpacing = theborderSpacing; - this.layerPos = 0.0f; - this.maxCrosswisePos = layeredGraph.getCrosswiseDim(); - this.maxLengthwiseAddPos = 0.0f; - - // add a left border if there are no input ports - Layer firstLayer = layeredGraph.getLayers().get(0); - if (firstLayer.getRank() != 0) { - layerPos = theborderSpacing; - } - // layout elements of the first layer - firstLayer.layoutElements(layerPos, theobjSpacing); - - // process all outgoing connections from each layer - ListIterator layerIter = layeredGraph.getLayers().listIterator(); - while (layerIter.hasNext()) { - Layer layer = layerIter.next(); - if (layerIter.hasNext()) { - // layout all outgoing connections of the current layer - processOutgoing(layer); - } - // layout element loops of the current layer - processLoops(layer); - } - - // update dimension of the whole graph - Layer lastLayer = layeredGraph.getLayers().get(layeredGraph.getLayers().size() - 1); - layerPos = lastLayer.getLengthwisePos() + lastLayer.getLengthwiseDim() + theborderSpacing; - if (layeredGraph.getLayoutDirection() == Direction.DOWN) { - layeredGraph.setCrosswiseDim(maxCrosswisePos + layeredGraph.getPosition().getX()); - layeredGraph.setLengthwiseDim(Math.max(layeredGraph.getLengthwiseDim(), layerPos - + maxLengthwiseAddPos + layeredGraph.getPosition().getY())); - } else { - layeredGraph.setCrosswiseDim(maxCrosswisePos + layeredGraph.getPosition().getY()); - layeredGraph.setLengthwiseDim(Math.max(layeredGraph.getLengthwiseDim(), layerPos - + maxLengthwiseAddPos + layeredGraph.getPosition().getX())); - } - - // process external ports - processExternalPorts(layeredGraph); - getMonitor().done(); - } - - /** - * Processes connections from a given layer to the subsequent one. - * - * @param layer layer to be processed - */ - private void processOutgoing(final Layer layer) { - Direction layoutDirection = layer.getLayeredGraph().getLayoutDirection(); - - // determine external routing options - Map routingMap - = new HashMap(); - int firstExtEdges = 0, lastExtEdges = 0, aroundExtEdges = 0; - for (LayerElement element : layer.getElements()) { - for (LayerConnection connection : element.getOutgoingConnections()) { - // determine source and target positions - ExternalRouting externalRouting = ExternalRouting.NORMAL; - if (layer.getRank() == 0 && connection.getSourcePort() != null) { - PortSide placement = connection.getSourcePort().getData(KShapeLayout.class) - .getProperty(LayoutOptions.PORT_SIDE); - if (layoutDirection == Direction.DOWN) { - if (placement == PortSide.WEST) { - externalRouting = ExternalRouting.FIRST; - firstExtEdges++; - } else if (placement == PortSide.EAST) { - externalRouting = ExternalRouting.LAST; - lastExtEdges++; - } else if (placement == PortSide.SOUTH) { - externalRouting = ExternalRouting.AROUND; - aroundExtEdges++; - } - } else { - if (placement == PortSide.NORTH) { - externalRouting = ExternalRouting.FIRST; - firstExtEdges++; - } else if (placement == PortSide.SOUTH) { - externalRouting = ExternalRouting.LAST; - lastExtEdges++; - } else if (placement == PortSide.EAST) { - externalRouting = ExternalRouting.AROUND; - aroundExtEdges++; - } - } - } else if (layer.getHeight() == 1 && connection.getTargetPort() != null) { - PortSide placement = connection.getTargetPort().getData(KShapeLayout.class) - .getProperty(LayoutOptions.PORT_SIDE); - if (layoutDirection == Direction.DOWN) { - if (placement == PortSide.WEST) { - externalRouting = ExternalRouting.FIRST; - firstExtEdges++; - } else if (placement == PortSide.EAST) { - externalRouting = ExternalRouting.LAST; - lastExtEdges++; - } else if (placement == PortSide.NORTH) { - externalRouting = ExternalRouting.AROUND; - aroundExtEdges++; - } - } else { - if (placement == PortSide.NORTH) { - externalRouting = ExternalRouting.FIRST; - firstExtEdges++; - } else if (placement == PortSide.SOUTH) { - externalRouting = ExternalRouting.LAST; - lastExtEdges++; - } else if (placement == PortSide.WEST) { - externalRouting = ExternalRouting.AROUND; - aroundExtEdges++; - } - } - } - routingMap.put(connection, externalRouting); - } - } - - // determine placement for all layer connections - layerwiseEdgePlacer.reset(getMonitor().subTask(1)); - int slotRanks = layerwiseEdgePlacer.placeEdges(layer, objSpacing); - Map slotMap = layerwiseEdgePlacer.getSlotMap(); - - // layout all movable elements of the next layer - KPoint layeredGraphPos = layer.getLayeredGraph().getPosition(); - float connectionsPos = layer.getLengthwisePos() + layer.getLengthwiseDim(); - if (slotRanks == 0 && (layer.getRank() == 0 || layer.getHeight() == 1)) { - connectionsPos += borderSpacing; - } else { - connectionsPos += objSpacing; - } - layerPos = connectionsPos + slotRanks * objSpacing; - layer.getNext().layoutElements(layerPos, objSpacing); - int firstExtIndex = 0, lastExtIndex = 0, aroundExtIndex = 0; - - // route connections from the current layer to the next one - for (LayerElement element : layer.getElements()) { - KPoint sourcePos = element.getPosition(); - KPoint sourceOffset = element.getPosOffset(); - float sourceXbase = sourcePos.getX() + sourceOffset.getX(); - float sourceYbase = sourcePos.getY() + sourceOffset.getY(); - for (LayerConnection connection : element.getOutgoingConnections()) { - // add back routing at source if needed - if (connection.getSourceBackPos() > 0) { - KPoint point1 = KLayoutDataFactory.eINSTANCE.createKPoint(); - KPoint point2 = KLayoutDataFactory.eINSTANCE.createKPoint(); - KShapeLayout portLayout = connection.getSourcePort().getData(KShapeLayout.class); - if (layoutDirection == Direction.DOWN) { - point1.setX(sourceXbase + portLayout.getXpos() + portLayout.getWidth() / 2); - point1.setY(sourcePos.getY() - connection.getSourceBackPos() * objSpacing); - point2.setX(connection.getSourceAnchorPos()); - point2.setY(point1.getY()); - } else { - point1.setY(sourceYbase + portLayout.getYpos() + portLayout.getHeight() / 2); - point1.setX(sourcePos.getX() - connection.getSourceBackPos() * objSpacing); - point2.setY(connection.getSourceAnchorPos()); - point2.setX(point1.getX()); - } - connection.getBendPoints().add(point1); - connection.getBendPoints().add(point2); - - // add side routing at source if needed - } else if (connection.getSourceSidePos() != 0) { - KPoint point = KLayoutDataFactory.eINSTANCE.createKPoint(); - KShapeLayout portLayout = connection.getSourcePort().getData(KShapeLayout.class); - if (layoutDirection == Direction.DOWN) { - point.setX(connection.getSourceAnchorPos()); - point.setY(sourceYbase + portLayout.getYpos() + portLayout.getHeight() / 2); - } else { - point.setY(connection.getSourceAnchorPos()); - point.setX(sourceXbase + portLayout.getXpos() + portLayout.getWidth() / 2); - } - connection.getBendPoints().add(point); - } - - Object key = connection.getSourcePort(); - if (key == null) { - key = element; - } - RoutingSlot slot = slotMap.get(key); - if (slot == null) { - key = connection.getTargetPort(); - if (key == null) { - key = connection.getTargetElement(); - } - slot = slotMap.get(key); - } - ExternalRouting externalRouting = routingMap.get(connection); - if (externalRouting == ExternalRouting.FIRST - || externalRouting == ExternalRouting.LAST) { - // perform routing to external port beside the layered graph - KPoint point1 = KLayoutDataFactory.eINSTANCE.createKPoint(); - KPoint point2 = KLayoutDataFactory.eINSTANCE.createKPoint(); - KPoint point3 = KLayoutDataFactory.eINSTANCE.createKPoint(); - if (layoutDirection == Direction.DOWN) { - if (externalRouting == ExternalRouting.FIRST) { - point1.setX(-(layeredGraphPos.getX() + firstExtIndex * objSpacing)); - firstExtIndex++; - } else { - point1.setX(maxCrosswisePos + (lastExtEdges - lastExtIndex - 1) - * objSpacing); - lastExtIndex++; - } - point2.setX(point1.getX()); - point2.setY(connectionsPos + slot.getRank() * objSpacing); - point3.setX(layer.getRank() == 0 ? connection.getTargetAnchorPos() - : connection.getSourceAnchorPos()); - point3.setY(point2.getY()); - } else { - if (externalRouting == ExternalRouting.FIRST) { - point1.setY(-(layeredGraphPos.getY() + firstExtIndex * objSpacing)); - firstExtIndex++; - } else { - point1.setY(maxCrosswisePos + (lastExtEdges - lastExtIndex - 1) - * objSpacing); - lastExtIndex++; - } - point2.setY(point1.getY()); - point2.setX(connectionsPos + slot.getRank() * objSpacing); - point3.setY(layer.getRank() == 0 ? connection.getTargetAnchorPos() - : connection.getSourceAnchorPos()); - point3.setX(point2.getX()); - } - if (layer.getRank() == 0) { - connection.getBendPoints().add(point1); - connection.getBendPoints().add(point2); - connection.getBendPoints().add(point3); - } else if (layer.getHeight() == 1) { - connection.getBendPoints().add(point3); - connection.getBendPoints().add(point2); - connection.getBendPoints().add(point1); - } - } else if (externalRouting == ExternalRouting.AROUND) { - // perform routing to external port on the opposite side - KPoint point1 = KLayoutDataFactory.eINSTANCE.createKPoint(); - KPoint point2 = KLayoutDataFactory.eINSTANCE.createKPoint(); - KPoint point3 = KLayoutDataFactory.eINSTANCE.createKPoint(); - KPoint point4 = KLayoutDataFactory.eINSTANCE.createKPoint(); - if (layoutDirection == Direction.DOWN) { - point1.setY(-aroundExtIndex * objSpacing); - point2.setY(point1.getY()); - if (layer.getRank() == 0) { - point4.setX(connection.getTargetAnchorPos()); - } else { - point4.setX(connection.getSourceAnchorPos()); - } - point2.setX(maxCrosswisePos - + (lastExtEdges + aroundExtEdges - aroundExtIndex - 1) * objSpacing); - point3.setX(point2.getX()); - point3.setY(connectionsPos + slot.getRank() * objSpacing); - point4.setY(point3.getY()); - } else { - point1.setX(-aroundExtIndex * objSpacing); - point2.setX(point1.getX()); - if (layer.getRank() == 0) { - point4.setY(connection.getTargetAnchorPos()); - } else { - point4.setY(connection.getSourceAnchorPos()); - } - point2.setY(maxCrosswisePos - + (lastExtEdges + aroundExtEdges - aroundExtIndex - 1) * objSpacing); - point3.setY(point2.getY()); - point3.setX(connectionsPos + slot.getRank() * objSpacing); - point4.setX(point3.getX()); - } - aroundExtIndex++; - if (layer.getRank() == 0) { - connection.getBendPoints().add(point1); - connection.getBendPoints().add(point2); - connection.getBendPoints().add(point3); - connection.getBendPoints().add(point4); - } else if (layer.getHeight() == 1) { - connection.getBendPoints().add(point4); - connection.getBendPoints().add(point3); - connection.getBendPoints().add(point2); - connection.getBendPoints().add(point1); - } - - } else if (connection.getSourceAnchorPos() != connection.getTargetAnchorPos()) { - // perform normal routing between anchor points - KPoint point1 = KLayoutDataFactory.eINSTANCE.createKPoint(); - KPoint point2 = KLayoutDataFactory.eINSTANCE.createKPoint(); - if (layoutDirection == Direction.DOWN) { - point1.setX(connection.getSourceAnchorPos()); - point1.setY(connectionsPos + slot.getRank() * objSpacing); - point2.setX(connection.getTargetAnchorPos()); - point2.setY(point1.getY()); - } else { - point1.setY(connection.getSourceAnchorPos()); - point1.setX(connectionsPos + slot.getRank() * objSpacing); - point2.setY(connection.getTargetAnchorPos()); - point2.setX(point1.getX()); - } - connection.getBendPoints().add(point1); - connection.getBendPoints().add(point2); - } - - // add front routing at target if needed - KPoint targetPos = connection.getTargetElement().getPosition(); - KPoint targetOffset = connection.getTargetElement().getPosOffset(); - float targetXbase = targetPos.getX() + targetOffset.getX(); - float targetYbase = targetPos.getY() + targetOffset.getY(); - if (connection.getTargetFrontPos() > 0) { - KPoint point1 = KLayoutDataFactory.eINSTANCE.createKPoint(); - KPoint point2 = KLayoutDataFactory.eINSTANCE.createKPoint(); - KShapeLayout portLayout = connection.getTargetPort().getData(KShapeLayout.class); - if (layoutDirection == Direction.DOWN) { - point1.setX(connection.getTargetAnchorPos()); - point1.setY(targetPos.getY() + connection.getTargetElement().getRealHeight() - + connection.getTargetFrontPos() * objSpacing); - point2.setX(targetXbase + portLayout.getXpos() + portLayout.getWidth() / 2); - point2.setY(point1.getY()); - } else { - point1.setY(connection.getTargetAnchorPos()); - point1.setX(targetPos.getX() + connection.getTargetElement().getRealWidth() - + connection.getTargetFrontPos() * objSpacing); - point2.setY(targetYbase + portLayout.getYpos() + portLayout.getHeight() / 2); - point2.setX(point1.getX()); - } - connection.getBendPoints().add(point1); - connection.getBendPoints().add(point2); - - // add side routing at target if needed - } else if (connection.getTargetSidePos() != 0) { - KPoint point = KLayoutDataFactory.eINSTANCE.createKPoint(); - KShapeLayout portLayout = connection.getTargetPort().getData(KShapeLayout.class); - if (layoutDirection == Direction.DOWN) { - point.setX(connection.getTargetAnchorPos()); - point.setY(targetYbase + portLayout.getYpos() + portLayout.getHeight() / 2); - } else { - point.setY(connection.getTargetAnchorPos()); - point.setX(targetXbase + portLayout.getXpos() + portLayout.getWidth() / 2); - } - connection.getBendPoints().add(point); - } - } - } - - // update dimension of the layered graph - if (layoutDirection == Direction.DOWN) { - layeredGraphPos.setX(layeredGraphPos.getX() + firstExtEdges * objSpacing); - if (layer.getHeight() == 0) { - layeredGraphPos.setY(layeredGraphPos.getY() + aroundExtEdges * objSpacing); - } - } else { - layeredGraphPos.setY(layeredGraphPos.getY() + firstExtEdges * objSpacing); - if (layer.getHeight() == 0) { - layeredGraphPos.setX(layeredGraphPos.getX() + aroundExtEdges * objSpacing); - } - } - maxCrosswisePos += (lastExtEdges + aroundExtEdges) * objSpacing; - if (layer.getRank() == 0) { - maxLengthwiseAddPos = aroundExtEdges * objSpacing; - } - } - - /** - * Routes element loops in a given layer. - * - * @param layer layer to process - */ - private void processLoops(final Layer layer) { - for (LayerElement element : layer.getElements()) { - for (ElementLoop loop : element.getLoops()) { - KPoint point1 = createPointFor(loop.getSourcePort(), element, loop); - KPoint point4 = createPointFor(loop.getTargetPort(), element, loop); - loop.getBendPoints().add(point1); - - PortSide placement1 = loop.getSourcePort().getData(KShapeLayout.class) - .getProperty(LayoutOptions.PORT_SIDE); - PortSide placement2 = loop.getTargetPort().getData(KShapeLayout.class) - .getProperty(LayoutOptions.PORT_SIDE); - if (placement1 != placement2) { - KPoint point2 = KLayoutDataFactory.eINSTANCE.createKPoint(); - KPoint point3 = KLayoutDataFactory.eINSTANCE.createKPoint(); - if (placement1 == PortSide.NORTH && placement2 == PortSide.SOUTH - || placement1 == PortSide.SOUTH && placement2 == PortSide.NORTH) { - point2.setX(element.getPosition().getX() + element.getRealWidth() - + loop.getRoutePos(PortSide.EAST) * objSpacing); - point2.setY(point1.getY()); - point3.setX(point2.getX()); - point3.setY(point4.getY()); - loop.getBendPoints().add(point2); - } else if (placement1 == PortSide.EAST && placement2 == PortSide.WEST - || placement1 == PortSide.WEST && placement2 == PortSide.EAST) { - point2.setX(point1.getX()); - point2.setY(element.getPosition().getY() + element.getRealHeight() - + loop.getRoutePos(PortSide.SOUTH) * objSpacing); - point3.setX(point4.getX()); - point3.setY(point2.getY()); - loop.getBendPoints().add(point2); - } else if (placement1 == PortSide.NORTH || placement1 == PortSide.SOUTH) { - point3.setX(point4.getX()); - point3.setY(point1.getY()); - } else { - point3.setX(point1.getX()); - point3.setY(point4.getY()); - } - loop.getBendPoints().add(point3); - } - loop.getBendPoints().add(point4); - } - } - } - - /** - * Process the external ports of a given layered graph by assigning missing - * coordinates. - * - * @param layeredGraph layered graph to process - */ - private void processExternalPorts(final LayeredGraph layeredGraph) { - Direction layoutDirection = layeredGraph.getLayoutDirection(); - Layer inputLayer = layeredGraph.getLayers().get(0); - Layer outputLayer = layeredGraph.getLayers().get(layeredGraph.getLayers().size() - 1); - - // determine maximal crosswise positions of input and output ports - float maxInputPos = 0.0f; - float maxOutputPos = 0.0f; - if (inputLayer.getRank() == 0) { - if (layoutDirection == Direction.DOWN) { - for (LayerElement element : inputLayer.getElements()) { - KPort port = (KPort) element.getElemObj(); - if (port.getData(KShapeLayout.class).getProperty(LayoutOptions.PORT_SIDE) - == PortSide.NORTH) { - maxInputPos = Math.max(maxInputPos, element.getPosition().getX()); - } - } - } else { - for (LayerElement element : inputLayer.getElements()) { - KPort port = (KPort) element.getElemObj(); - if (port.getData(KShapeLayout.class).getProperty(LayoutOptions.PORT_SIDE) - == PortSide.WEST) { - maxInputPos = Math.max(maxInputPos, element.getPosition().getY()); - } - } - } - } - if (outputLayer.getHeight() == 0) { - if (layoutDirection == Direction.DOWN) { - for (LayerElement element : outputLayer.getElements()) { - KPort port = (KPort) element.getElemObj(); - if (port.getData(KShapeLayout.class).getProperty(LayoutOptions.PORT_SIDE) - == PortSide.SOUTH) { - maxOutputPos = Math.max(maxOutputPos, element.getPosition().getX()); - } - } - } else { - for (LayerElement element : outputLayer.getElements()) { - KPort port = (KPort) element.getElemObj(); - if (port.getData(KShapeLayout.class).getProperty(LayoutOptions.PORT_SIDE) - == PortSide.EAST) { - maxOutputPos = Math.max(maxOutputPos, element.getPosition().getY()); - } - } - } - } - - // process input and output ports - if (inputLayer.getRank() == 0) { - processExternalLayer(layeredGraph, inputLayer, maxInputPos, maxOutputPos); - } - if (outputLayer.getHeight() == 0) { - processExternalLayer(layeredGraph, outputLayer, maxInputPos, maxOutputPos); - } - } - - /** - * Process a layer with external ports. - * - * @param layeredGraph the layered graph - * @param layer external layer - * @param maxInputPos maximal position of an input port on its home side - * @param maxOutputPos maximal position of an output port on its home side - */ - private void processExternalLayer(final LayeredGraph layeredGraph, - final Layer layer, final float maxInputPos, final float maxOutputPos) { - Direction layoutDirection = layeredGraph.getLayoutDirection(); - float offsetX = -layeredGraph.getPosition().getX(); - float offsetY = -layeredGraph.getPosition().getY(); - - // choose a placement for non-fixed ports - if (layeredGraph.getExternalPortConstraints() != PortConstraints.FIXED_POS) { - List northPorts = new LinkedList(); - List eastPorts = new LinkedList(); - List southPorts = new LinkedList(); - List westPorts = new LinkedList(); - for (LayerElement element : layer.getElements()) { - KPort port = (KPort) element.getElemObj(); - switch (port.getData(KShapeLayout.class).getProperty(LayoutOptions.PORT_SIDE)) { - case NORTH: - northPorts.add(element.getPosition()); - break; - case EAST: - eastPorts.add(element.getPosition()); - break; - case SOUTH: - southPorts.add(element.getPosition()); - break; - case WEST: - westPorts.add(element.getPosition()); - break; - } - } - if (layoutDirection == Direction.DOWN) { - if (layer.getRank() == 0) { - KimlUtil.placePoints(westPorts, 0.0f, layeredGraph.getLengthwiseDim() / 2, - offsetY, true, true); - KimlUtil.placePoints(eastPorts, 0.0f, layeredGraph.getLengthwiseDim() / 2, - offsetY, true, false); - KimlUtil.placePoints(southPorts, maxOutputPos, layeredGraph.getCrosswiseDim() - + offsetX, 0.0f, false, true); - } else { - KimlUtil.placePoints(westPorts, layeredGraph.getLengthwiseDim() / 2, - layeredGraph.getLengthwiseDim(), offsetY, true, true); - KimlUtil.placePoints(eastPorts, layeredGraph.getLengthwiseDim() / 2, - layeredGraph.getLengthwiseDim(), offsetY, true, false); - KimlUtil.placePoints(northPorts, maxInputPos, layeredGraph.getCrosswiseDim() - + offsetX, 0.0f, false, true); - } - } else { - if (layer.getRank() == 0) { - KimlUtil.placePoints(northPorts, 0.0f, layeredGraph.getLengthwiseDim() / 2, - offsetX, false, false); - KimlUtil.placePoints(southPorts, 0.0f, layeredGraph.getLengthwiseDim() / 2, - offsetX, false, true); - KimlUtil.placePoints(eastPorts, maxOutputPos, layeredGraph.getCrosswiseDim() - + offsetY, 0.0f, true, false); - } else { - KimlUtil.placePoints(northPorts, layeredGraph.getLengthwiseDim() / 2, - layeredGraph.getLengthwiseDim(), offsetX, false, true); - KimlUtil.placePoints(southPorts, layeredGraph.getLengthwiseDim() / 2, - layeredGraph.getLengthwiseDim(), offsetX, false, false); - KimlUtil.placePoints(westPorts, maxInputPos, layeredGraph.getCrosswiseDim() - + offsetY, 0.0f, true, false); - } - } - } - - // adjust the position of each external port - if (layoutDirection == Direction.DOWN) { - for (LayerElement element : layer.getElements()) { - KPort port = (KPort) element.getElemObj(); - KShapeLayout portLayout = port.getData(KShapeLayout.class); - KPoint position = element.getPosition(); - switch (portLayout.getProperty(LayoutOptions.PORT_SIDE)) { - case NORTH: - position.setY(offsetY - portLayout.getHeight()); - if (layer.getHeight() == 0) { - float posX = position.getX() + portLayout.getWidth() / 2; - for (LayerConnection connection : element.getIncomingConnections()) { - connection.getBendPoints().get(connection.getBendPoints().size() - 1) - .setX(posX); - } - } - break; - case EAST: - position.setX(layeredGraph.getCrosswiseDim() + offsetX); - float posY = position.getY() + portLayout.getHeight() / 2; - if (layer.getRank() == 0) { - for (LayerConnection connection : element.getOutgoingConnections()) { - connection.getBendPoints().get(0).setY(posY); - } - } else { - for (LayerConnection connection : element.getIncomingConnections()) { - connection.getBendPoints().get(connection.getBendPoints().size() - 1) - .setY(posY); - } - } - break; - case SOUTH: - position.setY(layeredGraph.getLengthwiseDim() + offsetY); - if (layer.getRank() == 0) { - float posX = position.getX() + portLayout.getWidth() / 2; - for (LayerConnection connection : element.getOutgoingConnections()) { - KPoint point1 = connection.getBendPoints().get(0); - KPoint point2 = connection.getBendPoints().get(1); - point1.setX(posX); - point1.setY(position.getY() + point1.getY()); - point2.setY(point1.getY()); - } - } - break; - case WEST: - position.setX(offsetX - portLayout.getWidth()); - posY = position.getY() + portLayout.getHeight() / 2; - if (layer.getRank() == 0) { - for (LayerConnection connection : element.getOutgoingConnections()) { - connection.getBendPoints().get(0).setY(posY); - } - } else { - for (LayerConnection connection : element.getIncomingConnections()) { - connection.getBendPoints().get(connection.getBendPoints().size() - 1) - .setY(posY); - } - } - break; - } - } - } else { - for (LayerElement element : layer.getElements()) { - KPort port = (KPort) element.getElemObj(); - KPoint position = element.getPosition(); - KShapeLayout portLayout = port.getData(KShapeLayout.class); - switch (portLayout.getProperty(LayoutOptions.PORT_SIDE)) { - case NORTH: - position.setY(offsetY - portLayout.getHeight()); - float posX = position.getX() + portLayout.getWidth() / 2; - if (layer.getRank() == 0) { - for (LayerConnection connection : element.getOutgoingConnections()) { - connection.getBendPoints().get(0).setX(posX); - } - } else { - for (LayerConnection connection : element.getIncomingConnections()) { - connection.getBendPoints().get(connection.getBendPoints().size() - 1) - .setX(posX); - } - } - break; - case EAST: - position.setX(layeredGraph.getLengthwiseDim() + offsetX); - if (layer.getRank() == 0) { - float posY = position.getY() + portLayout.getHeight() / 2; - for (LayerConnection connection : element.getOutgoingConnections()) { - KPoint point1 = connection.getBendPoints().get(0); - KPoint point2 = connection.getBendPoints().get(1); - point1.setY(posY); - point1.setX(position.getX() + point1.getX()); - point2.setX(point1.getX()); - } - } - break; - case SOUTH: - position.setY(layeredGraph.getCrosswiseDim() + offsetY); - posX = position.getX() + portLayout.getWidth() / 2; - if (layer.getRank() == 0) { - for (LayerConnection connection : element.getOutgoingConnections()) { - connection.getBendPoints().get(0).setX(posX); - } - } else { - for (LayerConnection connection : element.getIncomingConnections()) { - connection.getBendPoints().get(connection.getBendPoints().size() - 1) - .setX(posX); - } - } - break; - case WEST: - position.setX(offsetX - portLayout.getWidth()); - if (layer.getHeight() == 0) { - float posY = position.getY() + portLayout.getHeight() / 2; - for (LayerConnection connection : element.getIncomingConnections()) { - connection.getBendPoints().get(connection.getBendPoints().size() - 1) - .setY(posY); - } - } - break; - } - } - } - } - - /** - * Creates a point for routing of an element loop. - * - * @param port port where a point shall be created - * @param element the layer element - * @param loop element loop to be routed - * @return a point for edges starting or ending at the specified port - */ - private KPoint createPointFor(final KPort port, final LayerElement element, - final ElementLoop loop) { - KPoint elemPos = element.getPosition(); - KPoint elemOffset = element.getPosOffset(); - float xbase = elemPos.getX() + elemOffset.getX(); - float ybase = elemPos.getY() + elemOffset.getY(); - KPoint point = KLayoutDataFactory.eINSTANCE.createKPoint(); - KShapeLayout portLayout = port.getData(KShapeLayout.class); - switch (portLayout.getProperty(LayoutOptions.PORT_SIDE)) { - case NORTH: - point.setX(xbase + portLayout.getXpos() + portLayout.getWidth() / 2); - point.setY(elemPos.getY() - loop.getRoutePos(PortSide.NORTH) * objSpacing); - break; - case EAST: - point.setX(elemPos.getX() + element.getRealWidth() - + loop.getRoutePos(PortSide.EAST) * objSpacing); - point.setY(ybase + portLayout.getYpos() + portLayout.getHeight() / 2); - break; - case SOUTH: - point.setX(xbase + portLayout.getXpos() + portLayout.getWidth() / 2); - point.setY(elemPos.getY() + element.getRealHeight() - + loop.getRoutePos(PortSide.SOUTH) * objSpacing); - break; - case WEST: - point.setX(elemPos.getX() - loop.getRoutePos(PortSide.WEST) * objSpacing); - point.setY(ybase + portLayout.getYpos() + portLayout.getHeight() / 2); - break; - } - return point; - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/SortingLayerwiseEdgePlacer.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/SortingLayerwiseEdgePlacer.java (revision 239eb780788485f9211408ba8fbcc4c80d04aa0d) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/SortingLayerwiseEdgePlacer.java (revision 0) @@ -1,275 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2008 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.impl; - -import java.util.Arrays; -import java.util.Comparator; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; - -import de.cau.cs.kieler.core.alg.AbstractAlgorithm; -import de.cau.cs.kieler.kiml.klayoutdata.KShapeLayout; -import de.cau.cs.kieler.kiml.options.Direction; -import de.cau.cs.kieler.kiml.options.LayoutOptions; -import de.cau.cs.kieler.kiml.options.PortSide; -import de.cau.cs.kieler.klodd.hierarchical.modules.ILayerwiseEdgePlacer; -import de.cau.cs.kieler.klodd.hierarchical.structures.Layer; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayerConnection; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayerElement; -import de.cau.cs.kieler.klodd.hierarchical.structures.RoutingSlot; - -/** - * Layerwise edge placer implementation that sorts the edges and gives them slot - * ranks according to the result. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class SortingLayerwiseEdgePlacer extends AbstractAlgorithm implements ILayerwiseEdgePlacer { - - /** - * Routing slots used for sorting. - */ - private static class SortableRoutingSlot extends RoutingSlot { - private boolean outgoingAtStart = false, outgoingAtEnd = false; - } - - /** minimal distance of two edges to make them feasible in the same routing layer. */ - private static final float EDGE_DIST = 2.0f; - - /** map of layer elements to their corresponding routing slots. */ - private Map slotMap = new LinkedHashMap(); - - /** - * {@inheritDoc} - */ - @Override - public void reset() { - super.reset(); - slotMap.clear(); - } - - /** - * {@inheritDoc} - */ - public int placeEdges(final Layer layer, final float minDist) { - getMonitor().begin("Edge routing (layer " + layer.getRank() + ")", 1); - Direction layoutDirection = layer.getLayeredGraph().getLayoutDirection(); - - // determine number of outgoing connections for each port - Map outgoing = new HashMap(); - for (LayerElement element : layer.getElements()) { - // count outgoing connections - for (LayerConnection connection : element.getOutgoingConnections()) { - Object key = connection.getSourcePort(); - if (key == null) { - key = element; - } - Integer value = outgoing.get(key); - if (value == null) { - outgoing.put(key, Integer.valueOf(1)); - } else { - outgoing.put(key, Integer.valueOf(value.intValue() + 1)); - } - } - } - - // create routing slots for each port - for (LayerElement element : layer.getElements()) { - for (LayerConnection connection : element.getOutgoingConnections()) { - // choose source or target port for routing - Object key = connection.getSourcePort(); - if (key == null) { - key = element; - } - Integer sourceValue = outgoing.get(key); - if (sourceValue == null || sourceValue.intValue() <= 1) { - key = connection.getTargetPort(); - if (key == null) { - key = connection.getTargetElement(); - } - } - - // determine source and target positions - float sourcePos = connection.calcSourcePos(minDist); - float targetPos = connection.calcTargetPos(minDist); - if (layer.getRank() == 0) { - PortSide placement = connection.getSourcePort().getData(KShapeLayout.class) - .getProperty(LayoutOptions.PORT_SIDE); - if (layoutDirection == Direction.DOWN) { - if (placement == PortSide.WEST) { - sourcePos = 0.0f; - } else if (placement == PortSide.EAST) { - sourcePos = layer.getCrosswiseDim(); - } else if (placement == PortSide.SOUTH) { - sourcePos = layer.getCrosswiseDim(); - } - } else { - if (placement == PortSide.NORTH) { - sourcePos = 0.0f; - } else if (placement == PortSide.SOUTH) { - sourcePos = layer.getCrosswiseDim(); - } else if (placement == PortSide.EAST) { - sourcePos = layer.getCrosswiseDim(); - } - } - } else if (layer.getHeight() == 1) { - PortSide placement = connection.getTargetPort().getData(KShapeLayout.class) - .getProperty(LayoutOptions.PORT_SIDE); - if (layoutDirection == Direction.DOWN) { - if (placement == PortSide.WEST) { - targetPos = 0.0f; - } else if (placement == PortSide.EAST) { - targetPos = layer.getCrosswiseDim(); - } else if (placement == PortSide.NORTH) { - targetPos = layer.getCrosswiseDim(); - } - } else { - if (placement == PortSide.NORTH) { - targetPos = 0.0f; - } else if (placement == PortSide.SOUTH) { - targetPos = layer.getCrosswiseDim(); - } else if (placement == PortSide.WEST) { - targetPos = layer.getCrosswiseDim(); - } - } - } - float startPos = Math.min(sourcePos, targetPos) - EDGE_DIST; - float endPos = Math.max(sourcePos, targetPos) + EDGE_DIST; - - // get routing slot and insert connection area - SortableRoutingSlot slot = (SortableRoutingSlot) slotMap.get(key); - if (slot == null) { - slot = new SortableRoutingSlot(); - if (targetPos <= sourcePos) { - slot.outgoingAtStart = true; - } - if (targetPos >= sourcePos) { - slot.outgoingAtEnd = true; - } - slot.setStart(startPos); - slot.setEnd(endPos); - slotMap.put(key, slot); - } else { - if (startPos < slot.getStart()) { - if (targetPos <= sourcePos) { - slot.outgoingAtStart = true; - } else { - slot.outgoingAtStart = false; - } - } - if (endPos > slot.getEnd()) { - if (targetPos >= sourcePos) { - slot.outgoingAtEnd = true; - } else { - slot.outgoingAtEnd = false; - } - } - slot.setStart(Math.min(slot.getStart(), startPos)); - slot.setEnd(Math.max(slot.getEnd(), endPos)); - } - } - } - - // sort all routing slots - List> routingLayers = new LinkedList>(); - RoutingSlot[] sortedSlots = slotMap.values().toArray(new RoutingSlot[0]); - Arrays.sort(sortedSlots, new Comparator() { - public int compare(final RoutingSlot s1, final RoutingSlot s2) { - assert s1 instanceof SortableRoutingSlot && s2 instanceof SortableRoutingSlot; - SortableRoutingSlot slot1 = (SortableRoutingSlot) s1; - SortableRoutingSlot slot2 = (SortableRoutingSlot) s2; - if (slot1.outgoingAtStart && !slot2.outgoingAtStart - && slot1.getStart() == slot2.getStart()) { - return 1; - } else if (slot2.outgoingAtStart && !slot1.outgoingAtStart - && slot1.getStart() == slot2.getStart()) { - return -1; - } else if (slot1.outgoingAtEnd && !slot2.outgoingAtEnd - && slot1.getEnd() == slot2.getEnd()) { - return 1; - } else if (slot2.outgoingAtEnd && !slot1.outgoingAtEnd - && slot1.getEnd() == slot2.getEnd()) { - return -1; - } else if (slot1.outgoingAtStart && slot1.getStart() > slot2.getStart()) { - return 1; - } else if (slot2.outgoingAtStart && slot2.getStart() > slot1.getStart()) { - return -1; - } else if (slot1.outgoingAtEnd && slot1.getEnd() < slot2.getEnd()) { - return 1; - } else if (slot2.outgoingAtEnd && slot2.getEnd() < slot1.getEnd()) { - return -1; - } else if (!slot1.outgoingAtStart && slot1.getStart() > slot2.getStart()) { - return -1; - } else if (!slot2.outgoingAtStart && slot2.getStart() > slot1.getStart()) { - return 1; - } else if (!slot1.outgoingAtEnd && slot1.getEnd() < slot2.getEnd()) { - return -1; - } else if (!slot2.outgoingAtEnd && slot2.getEnd() < slot1.getEnd()) { - return 1; - } else { - return 0; - } - } - }); - // assign ranks to each routing slot - int slotRanks = 0; - for (RoutingSlot slot : sortedSlots) { - int rank = routingLayers.size(); - ListIterator> routingLayerIter = routingLayers.listIterator(routingLayers - .size()); - List lastLayer = null; - while (routingLayerIter.hasPrevious()) { - List routingLayer = routingLayerIter.previous(); - boolean feasible = true; - for (RoutingSlot layerSlot : routingLayer) { - if (slot.getStart() < layerSlot.getEnd() && slot.getEnd() > layerSlot.getStart()) { - feasible = false; - break; - } - } - if (!feasible) { - break; - } - lastLayer = routingLayer; - rank--; - } - if (lastLayer != null) { - slot.setRank(rank); - lastLayer.add(slot); - } else { - slot.setRank(routingLayers.size()); - List routingLayer = new LinkedList(); - routingLayer.add(slot); - routingLayers.add(routingLayer); - slotRanks++; - } - } - - getMonitor().done(); - return slotRanks; - } - - /** - * {@inheritDoc} - */ - public Map getSlotMap() { - return slotMap; - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/SortingNodewiseEdgePlacer.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/SortingNodewiseEdgePlacer.java (revision 239eb780788485f9211408ba8fbcc4c80d04aa0d) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/SortingNodewiseEdgePlacer.java (revision 0) @@ -1,658 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2008 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.impl; - -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; - -import de.cau.cs.kieler.core.alg.AbstractAlgorithm; -import de.cau.cs.kieler.core.kgraph.KEdge; -import de.cau.cs.kieler.core.kgraph.KNode; -import de.cau.cs.kieler.core.kgraph.KPort; -import de.cau.cs.kieler.kiml.klayoutdata.KShapeLayout; -import de.cau.cs.kieler.kiml.options.Direction; -import de.cau.cs.kieler.kiml.options.LayoutOptions; -import de.cau.cs.kieler.kiml.options.PortSide; -import de.cau.cs.kieler.klodd.hierarchical.modules.INodewiseEdgePlacer; -import de.cau.cs.kieler.klodd.hierarchical.structures.ElementLoop; -import de.cau.cs.kieler.klodd.hierarchical.structures.Layer; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayerConnection; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayerElement; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayeredGraph; - -/** - * Nodewise edge placer implementation that sorts the edges and gives them slot - * ranks according to the result. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class SortingNodewiseEdgePlacer extends AbstractAlgorithm implements INodewiseEdgePlacer { - - /** - * Routing slot used to route edges around node elements. - */ - private static class RoutingSlot implements Comparable { - private float start = -Float.MAX_VALUE, end = Float.MAX_VALUE; - private int rank; - private List ports = new LinkedList(); - - /** - * {@inheritDoc} - */ - public int compareTo(final RoutingSlot other) { - if (this.start <= other.start && this.end >= other.end) { - return 1; - } else if (this.start >= other.start && this.end <= other.end) { - return -1; - } else { - return 0; - } - } - - /** - * {@inheritDoc} - */ - @Override - public boolean equals(final Object other) { - if (other instanceof RoutingSlot) { - return this.compareTo((RoutingSlot) other) == 0; - } else { - return false; - } - } - - /** - * {@inheritDoc} - */ - @Override - public int hashCode() { - return ((int) start << (Integer.SIZE / 2)) + (int) end; - } - } - - /** layout direction configured for the given layered graph. */ - private Direction layoutDirection; - - /** - * {@inheritDoc} - */ - public void placeEdges(final LayeredGraph layeredGraph) { - getMonitor().begin("Nodewise edge placement", 1); - - layoutDirection = layeredGraph.getLayoutDirection(); - // calculate the connection routing for each layer element - for (Layer layer : layeredGraph.getLayers()) { - for (LayerElement element : layer.getElements()) { - element.placePorts(); - placeEdges(element); - } - } - - getMonitor().done(); - } - - /** - * Calculates placements for the edges incident with the given layer - * element, if its element object is a regular node. - * - * @param element layer element to process - */ - private void placeEdges(final LayerElement element) { - Object elemObj = element.getElemObj(); - if (!(elemObj instanceof KNode)) { - return; - } - KNode node = (KNode) elemObj; - if (node.getPorts().isEmpty()) { - return; - } - List northSlots = new LinkedList(); - List eastSlots = new LinkedList(); - List southSlots = new LinkedList(); - List westSlots = new LinkedList(); - Map northMap = new HashMap(); - Map eastMap = new HashMap(); - Map southMap = new HashMap(); - Map westMap = new HashMap(); - float nodeWidth = element.getRealWidth(); - float nodeHeight = element.getRealHeight(); - - for (KPort port1 : node.getPorts()) { - KShapeLayout portLayout = port1.getData(KShapeLayout.class); - PortSide placement = portLayout.getProperty(LayoutOptions.PORT_SIDE); - float xPos1 = portLayout.getXpos() + portLayout.getWidth() / 2; - float yPos1 = portLayout.getYpos() + portLayout.getHeight() / 2; - // process self-loops over the given port - for (KEdge edge : port1.getEdges()) { - if (edge.getSourcePort() == port1 && edge.getTarget() == node) { - KPort port2 = edge.getTargetPort(); - ElementLoop loop = new ElementLoop(edge, element, port1, port2); - element.getLoops().add(loop); - KShapeLayout targetLayout = port2.getData(KShapeLayout.class); - PortSide placement2 = targetLayout.getProperty(LayoutOptions.PORT_SIDE); - float xPos2 = targetLayout.getXpos() + targetLayout.getWidth() / 2; - float yPos2 = targetLayout.getYpos() + targetLayout.getHeight() / 2; - switch (placement) { - case NORTH: - switch (placement2) { - case NORTH: - addToSlot(port1, port2, northSlots, northMap, Math.min(xPos1, xPos2), Math - .max(xPos1, xPos2)); - break; - case EAST: - addToSlot(port1, port2, northSlots, northMap, xPos1, nodeWidth + yPos2); - addToSlot(port1, port2, eastSlots, eastMap, xPos1 - nodeWidth, yPos2); - break; - case SOUTH: - addToSlot(port1, port2, northSlots, northMap, xPos1, 2 * nodeWidth - + nodeHeight - xPos2); - addToSlot(port1, port2, eastSlots, eastMap, xPos1 - nodeWidth, nodeHeight - + nodeWidth - xPos2); - addToSlot(port1, port2, southSlots, southMap, - xPos1 - nodeHeight - nodeWidth, nodeWidth - xPos2); - break; - case WEST: - addToSlot(port1, port2, northSlots, northMap, -yPos2, xPos1); - addToSlot(port1, port2, westSlots, westMap, nodeHeight - yPos2, nodeHeight - + xPos1); - break; - } - break; - case EAST: - switch (placement2) { - case NORTH: - addToSlot(port1, port2, eastSlots, eastMap, xPos2 - nodeWidth, yPos1); - addToSlot(port1, port2, northSlots, northMap, xPos2, nodeWidth + yPos1); - break; - case EAST: - addToSlot(port1, port2, eastSlots, eastMap, Math.min(yPos1, yPos2), Math - .max(yPos1, yPos2)); - break; - case SOUTH: - addToSlot(port1, port2, eastSlots, eastMap, yPos1, nodeHeight + nodeWidth - - xPos2); - addToSlot(port1, port2, southSlots, southMap, yPos1 - nodeHeight, nodeWidth - - xPos2); - break; - case WEST: - addToSlot(port1, port2, eastSlots, eastMap, yPos1, 2 * nodeHeight - + nodeWidth - yPos2); - addToSlot(port1, port2, southSlots, southMap, yPos1 - nodeHeight, nodeWidth - + nodeHeight - yPos2); - addToSlot(port1, port2, westSlots, westMap, yPos1 - nodeWidth - nodeHeight, - nodeHeight - yPos2); - break; - } - break; - case SOUTH: - switch (placement2) { - case NORTH: - addToSlot(port1, port2, southSlots, southMap, - xPos2 - nodeHeight - nodeWidth, nodeWidth - xPos1); - addToSlot(port1, port2, eastSlots, eastMap, xPos2 - nodeWidth, nodeHeight - + nodeWidth - xPos1); - addToSlot(port1, port2, northSlots, northMap, xPos2, 2 * nodeWidth - + nodeHeight - xPos1); - break; - case EAST: - addToSlot(port1, port2, southSlots, southMap, yPos2 - nodeHeight, nodeWidth - - xPos1); - addToSlot(port1, port2, eastSlots, eastMap, yPos2, nodeHeight + nodeWidth - - xPos1); - break; - case SOUTH: - addToSlot(port1, port2, southSlots, southMap, nodeWidth - - Math.max(xPos1, xPos2), nodeWidth - Math.min(xPos1, xPos2)); - break; - case WEST: - addToSlot(port1, port2, southSlots, southMap, nodeWidth - xPos1, nodeWidth - + nodeHeight - yPos2); - addToSlot(port1, port2, westSlots, westMap, -xPos1, nodeHeight - yPos2); - break; - } - break; - case WEST: - switch (placement2) { - case NORTH: - addToSlot(port1, port2, westSlots, westMap, nodeHeight - yPos1, nodeHeight - + xPos2); - addToSlot(port1, port2, northSlots, northMap, -yPos1, xPos2); - break; - case EAST: - addToSlot(port1, port2, westSlots, westMap, yPos2 - nodeWidth - nodeHeight, - nodeHeight - yPos1); - addToSlot(port1, port2, southSlots, southMap, yPos2 - nodeHeight, nodeWidth - + nodeHeight - yPos1); - addToSlot(port1, port2, eastSlots, eastMap, yPos2, 2 * nodeHeight - + nodeWidth - yPos1); - break; - case SOUTH: - addToSlot(port1, port2, westSlots, westMap, -xPos2, nodeHeight - yPos1); - addToSlot(port1, port2, southSlots, southMap, nodeWidth - xPos2, nodeWidth - + nodeHeight - yPos1); - break; - case WEST: - addToSlot(port1, port2, westSlots, westMap, nodeHeight - - Math.max(yPos1, yPos2), nodeHeight - Math.min(yPos1, yPos2)); - break; - } - break; - } - } - } - - // process routing to other layers - if (layoutDirection == Direction.DOWN) { - switch (placement) { - case NORTH: - if (hasOutgoing(element, port1)) { - addToSlot(node, port1, northSlots, northMap, xPos1, Float.MAX_VALUE); - addToSlot(node, port1, eastSlots, eastMap, xPos1 - nodeWidth, Float.MAX_VALUE); - } - break; - case EAST: - float fromPos = yPos1, - toPos = yPos1; - if (hasOutgoing(element, port1)) { - toPos = Float.MAX_VALUE; - } - if (hasIncoming(element, port1)) { - fromPos = -Float.MAX_VALUE; - } - if (!equal(fromPos, toPos)) { - addToSlot(node, port1, eastSlots, eastMap, fromPos, toPos); - } - break; - case SOUTH: - if (hasIncoming(element, port1)) { - addToSlot(node, port1, southSlots, southMap, -Float.MAX_VALUE, - nodeWidth - xPos1); - addToSlot(node, port1, eastSlots, eastMap, -Float.MAX_VALUE, - nodeHeight + nodeWidth - xPos1); - } - break; - case WEST: - fromPos = nodeHeight - yPos1; - toPos = fromPos; - if (hasOutgoing(element, port1)) { - fromPos = -Float.MAX_VALUE; - } - if (hasIncoming(element, port1)) { - toPos = Float.MAX_VALUE; - } - if (fromPos != toPos) { - addToSlot(node, port1, westSlots, westMap, fromPos, toPos); - } - break; - } - } else { - switch (placement) { - case NORTH: - float fromPos = xPos1, - toPos = xPos1; - if (hasOutgoing(element, port1)) { - toPos = Float.MAX_VALUE; - } - if (hasIncoming(element, port1)) { - fromPos = -Float.MAX_VALUE; - } - if (fromPos != toPos) { - addToSlot(node, port1, northSlots, northMap, fromPos, toPos); - } - break; - case EAST: - if (hasIncoming(element, port1)) { - addToSlot(node, port1, eastSlots, eastMap, yPos1, Float.MAX_VALUE); - addToSlot(node, port1, southSlots, southMap, yPos1 - nodeHeight, - Float.MAX_VALUE); - } - break; - case SOUTH: - fromPos = nodeWidth - xPos1; - toPos = fromPos; - if (hasOutgoing(element, port1)) { - fromPos = -Float.MAX_VALUE; - } - if (hasIncoming(element, port1)) { - toPos = Float.MAX_VALUE; - } - if (fromPos != toPos) { - addToSlot(node, port1, southSlots, southMap, fromPos, toPos); - } - break; - case WEST: - if (hasOutgoing(element, port1)) { - addToSlot(node, port1, westSlots, westMap, -Float.MAX_VALUE, nodeHeight - yPos1); - addToSlot(node, port1, southSlots, southMap, -Float.MAX_VALUE, nodeWidth - + nodeHeight - yPos1); - } - break; - } - } - } - - // assign ranks to all routing slots - element.setRanks(assignRanks(northSlots), PortSide.NORTH); - element.setRanks(assignRanks(eastSlots), PortSide.EAST); - element.setRanks(assignRanks(southSlots), PortSide.SOUTH); - element.setRanks(assignRanks(westSlots), PortSide.WEST); - - // calculate edge routing for all incoming or outgoing connections - if (layoutDirection == Direction.DOWN) { - for (LayerConnection connection : element.getIncomingConnections()) { - KPort port = connection.getTargetPort(); - if (port != null) { - switch (port.getData(KShapeLayout.class).getProperty(LayoutOptions.PORT_SIDE)) { - case EAST: - int rank = getRankFor(port, eastSlots, element.getRanks(PortSide.EAST)); - connection.setTargetSidePos(rank); - break; - case SOUTH: - rank = getRankFor(port, eastSlots, element.getRanks(PortSide.EAST)); - connection.setTargetSidePos(rank); - rank = getRankFor(port, southSlots, element.getRanks(PortSide.SOUTH)); - connection.setTargetFrontPos(rank); - break; - case WEST: - rank = getRankFor(port, westSlots, element.getRanks(PortSide.WEST)); - connection.setTargetSidePos(-rank); - break; - } - } - } - for (LayerConnection connection : element.getOutgoingConnections()) { - KPort port = connection.getSourcePort(); - if (port != null) { - switch (port.getData(KShapeLayout.class).getProperty(LayoutOptions.PORT_SIDE)) { - case NORTH: - int rank = getRankFor(port, eastSlots, element.getRanks(PortSide.EAST)); - connection.setSourceSidePos(rank); - rank = getRankFor(port, northSlots, element.getRanks(PortSide.NORTH)); - connection.setSourceBackPos(rank); - break; - case EAST: - rank = getRankFor(port, eastSlots, element.getRanks(PortSide.EAST)); - connection.setSourceSidePos(rank); - break; - case WEST: - rank = getRankFor(port, westSlots, element.getRanks(PortSide.WEST)); - connection.setSourceSidePos(-rank); - break; - } - } - } - } else { - for (LayerConnection connection : element.getIncomingConnections()) { - KPort port = connection.getTargetPort(); - if (port != null) { - switch (port.getData(KShapeLayout.class).getProperty(LayoutOptions.PORT_SIDE)) { - case SOUTH: - int rank = getRankFor(port, southSlots, element.getRanks(PortSide.SOUTH)); - connection.setTargetSidePos(rank); - break; - case EAST: - rank = getRankFor(port, southSlots, element.getRanks(PortSide.SOUTH)); - connection.setTargetSidePos(rank); - rank = getRankFor(port, eastSlots, element.getRanks(PortSide.EAST)); - connection.setTargetFrontPos(rank); - break; - case NORTH: - rank = getRankFor(port, northSlots, element.getRanks(PortSide.NORTH)); - connection.setTargetSidePos(-rank); - break; - } - } - } - for (LayerConnection connection : element.getOutgoingConnections()) { - KPort port = connection.getSourcePort(); - if (port != null) { - switch (port.getData(KShapeLayout.class).getProperty(LayoutOptions.PORT_SIDE)) { - case WEST: - int rank = getRankFor(port, southSlots, element.getRanks(PortSide.SOUTH)); - connection.setSourceSidePos(rank); - rank = getRankFor(port, westSlots, element.getRanks(PortSide.WEST)); - connection.setSourceBackPos(rank); - break; - case SOUTH: - rank = getRankFor(port, southSlots, element.getRanks(PortSide.SOUTH)); - connection.setSourceSidePos(rank); - break; - case NORTH: - rank = getRankFor(port, northSlots, element.getRanks(PortSide.NORTH)); - connection.setSourceSidePos(-rank); - break; - } - } - } - } - - // calculate edge routing for all element loops - for (ElementLoop loop : element.getLoops()) { - PortSide placement1 = loop.getSourcePort().getData(KShapeLayout.class) - .getProperty(LayoutOptions.PORT_SIDE); - PortSide placement2 = loop.getTargetPort().getData(KShapeLayout.class) - .getProperty(LayoutOptions.PORT_SIDE); - if (placement1 == PortSide.NORTH || placement2 == PortSide.NORTH) { - int rank = getRankFor(loop.getSourcePort(), northSlots, - element.getRanks(PortSide.NORTH)); - loop.setRoutePos(rank, PortSide.NORTH); - } - if (placement1 == PortSide.EAST || placement2 == PortSide.EAST - || placement1 == PortSide.NORTH && placement2 == PortSide.SOUTH - || placement1 == PortSide.SOUTH && placement2 == PortSide.NORTH) { - int rank = getRankFor(loop.getSourcePort(), eastSlots, element.getRanks(PortSide.EAST)); - loop.setRoutePos(rank, PortSide.EAST); - } - if (placement1 == PortSide.SOUTH || placement2 == PortSide.SOUTH - || placement1 == PortSide.EAST && placement2 == PortSide.WEST - || placement1 == PortSide.WEST && placement2 == PortSide.EAST) { - int rank = getRankFor(loop.getSourcePort(), southSlots, - element.getRanks(PortSide.SOUTH)); - loop.setRoutePos(rank, PortSide.SOUTH); - } - if (placement1 == PortSide.WEST || placement2 == PortSide.WEST) { - int rank = getRankFor(loop.getSourcePort(), westSlots, element.getRanks(PortSide.WEST)); - loop.setRoutePos(rank, PortSide.WEST); - } - } - } - - /** - * Adds a given port to an appropriate routing slot. - * - * @param node layout node that is being processed - * @param port port to be inserted - * @param slotList list of existing routing slots - * @param slotMap mapping of ports to existing slots - * @param fromPos starting position for the given port - * @param toPos ending position for the given port - */ - private void addToSlot(final KNode node, final KPort port, final List slotList, - final Map slotMap, final float fromPos, final float toPos) { - RoutingSlot slot = slotMap.get(port); - if (slot == null && port.getEdges().size() == 1) { - KEdge edge = port.getEdges().get(0); - if (edge.getSourcePort() != port && edge.getSource() != node) { - slot = slotMap.get(edge.getSourcePort()); - if (slot == null) { - slot = new RoutingSlot(); - slotList.add(slot); - slotMap.put(edge.getSourcePort(), slot); - } - } else if (edge.getTargetPort() != port && edge.getTarget() != node) { - slot = slotMap.get(edge.getTargetPort()); - if (slot == null) { - slot = new RoutingSlot(); - slotList.add(slot); - slotMap.put(edge.getTargetPort(), slot); - } - } - } - if (slot == null) { - slot = new RoutingSlot(); - slotList.add(slot); - } - if (!slot.ports.contains(port)) { - slot.ports.add(port); - } - slot.start = Math.max(slot.start, fromPos); - slot.end = Math.min(slot.end, toPos); - } - - /** - * Adds two ports to an appropriate routing slot. - * - * @param port1 first port to be inserted - * @param port2 second port to be inserted - * @param slotList list of existing routing slots - * @param slotMap mapping of ports to existing slots - * @param fromPos starting position for the given port - * @param toPos ending position for the given port - */ - private void addToSlot(final KPort port1, final KPort port2, final List slotList, - final Map slotMap, final float fromPos, final float toPos) { - RoutingSlot slot = slotMap.get(port1); - if (slot == null) { - slot = slotMap.get(port2); - } - if (slot == null) { - slot = new RoutingSlot(); - slotList.add(slot); - slotMap.put(port1, slot); - slotMap.put(port2, slot); - } - if (!slot.ports.contains(port1)) { - slot.ports.add(port1); - } - if (!slot.ports.contains(port2)) { - slot.ports.add(port2); - } - slot.start = Math.max(slot.start, fromPos); - slot.end = Math.min(slot.end, toPos); - } - - /** - * Determines whether the given port has an outgoing connection. - * - * @param element layer element that is being processed - * @param port port to check - * @return true if the given port has an outgoing connection - */ - private boolean hasOutgoing(final LayerElement element, final KPort port) { - for (LayerConnection connection : element.getOutgoingConnections()) { - if (connection.getSourcePort() == port && connection.getTargetElement() != element) { - return true; - } - } - return false; - } - - /** - * Determines whether the given port has an incoming connection. - * - * @param element layer element that is being processed - * @param port port to check - * @return true if the given port has an incoming connection - */ - private boolean hasIncoming(final LayerElement element, final KPort port) { - for (LayerConnection connection : element.getIncomingConnections()) { - if (connection.getTargetPort() == port && connection.getSourceElement() != element) { - return true; - } - } - return false; - } - - /** - * Assigns slot ranks to all slots of a given list. - * - * @param slotList list of slot ranks - * @return number of assigned slot ranks - */ - private int assignRanks(final List slotList) { - // sort list by start and end values using insertion sort - LinkedList sortedList = new LinkedList(); - for (RoutingSlot slot : slotList) { - ListIterator slotIter = sortedList.listIterator(); - while (slotIter.hasNext()) { - if (slotIter.next().compareTo(slot) > 0) { - slotIter.previous(); - break; - } - } - slotIter.add(slot); - } - - // assign ranks to each routing slot - int slotRanks = 0; - List> routingLayers = new LinkedList>(); - for (RoutingSlot slot : sortedList) { - boolean foundPlace = false; - int rank = 1; - for (List routingLayer : routingLayers) { - boolean feasible = true; - for (RoutingSlot layerSlot : routingLayer) { - if (slot.start < layerSlot.end && slot.end > layerSlot.start) { - feasible = false; - break; - } - } - if (feasible) { - slot.rank = rank; - routingLayer.add(slot); - foundPlace = true; - break; - } - rank++; - } - if (!foundPlace) { - slot.rank = rank; - List routingLayer = new LinkedList(); - routingLayer.add(slot); - routingLayers.add(routingLayer); - slotRanks++; - } - } - - return slotRanks; - } - - /** - * Returns the routing rank for a given port. - * - * @param port port to look up - * @param slotList list of available routing slots - * @param ranks number of assigned ranks - * @return the assigned rank, or ranks if no rank is found - */ - private int getRankFor(final KPort port, final List slotList, final int ranks) { - for (RoutingSlot slot : slotList) { - if (slot.ports.contains(port)) { - return slot.rank; - } - } - return ranks; - } - - private static final float EQUAL_THRES = 0.0001f; - - private static boolean equal(final float f1, final float f2) { - return Math.abs(f1 - f2) < EQUAL_THRES; - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/ToponumLayerwiseEdgePlacer.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/ToponumLayerwiseEdgePlacer.java (revision 239eb780788485f9211408ba8fbcc4c80d04aa0d) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/ToponumLayerwiseEdgePlacer.java (revision 0) @@ -1,454 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.impl; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; - -import de.cau.cs.kieler.core.alg.AbstractAlgorithm; -import de.cau.cs.kieler.core.util.Pair; -import de.cau.cs.kieler.kiml.klayoutdata.KShapeLayout; -import de.cau.cs.kieler.kiml.options.Direction; -import de.cau.cs.kieler.kiml.options.LayoutOptions; -import de.cau.cs.kieler.kiml.options.PortSide; -import de.cau.cs.kieler.klodd.hierarchical.modules.ILayerwiseEdgePlacer; -import de.cau.cs.kieler.klodd.hierarchical.structures.Layer; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayerConnection; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayerElement; -import de.cau.cs.kieler.klodd.hierarchical.structures.RoutingSlot; - -/** - * Layerwise edge placer implementation that orders routing slots using - * topological numbering. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class ToponumLayerwiseEdgePlacer extends AbstractAlgorithm implements ILayerwiseEdgePlacer { - - /** value returned by comparator if the 'greater than' relation is strong. */ - private static final int STRONGLY_GREATER = 2; - /** value returned by comparator if the 'less than' relation is strong. */ - private static final int STRONGLY_LESS = -2; - - /** - * Routing slot used for sorting. - */ - private class TopoRoutingSlot extends RoutingSlot implements Comparable { - - /** positions of line segments going to the preceding layer. */ - private List sourcePosis = new LinkedList(); - /** positions of line segments going to the next layer. */ - private List targetPosis = new LinkedList(); - /** - * list of outgoing links in the slot ordering graph; the second entry - * indicates whether this is a strong link. - */ - private List> outgoing - = new LinkedList>(); - /** number of incoming links in the slot ordering graph. */ - private int incomingCount = 0; - /** visit marker for cycle breaking. */ - private int visit = -1; - - /** - * Compares two routing slots. Returns a number greater than zero if - * this slot should be put behind the other slot, or a number less than - * zero if this slot should be put in front of the other slot. If the - * relation is a strong one (there are conflicts between edges), the - * result is -2 or 2, else it is -1, 0, or 1. - * - * @param o the other routing slot to compare with this one - * @return a number between -2 and 2 (included) - */ - public int compareTo(final TopoRoutingSlot other) { - // compare number of conflicts for both variants - int conflicts1 = countConflicts(this.targetPosis, other.sourcePosis); - int conflicts2 = countConflicts(other.targetPosis, this.sourcePosis); - if (conflicts1 > conflicts2) { - return STRONGLY_GREATER; - } else if (conflicts1 < conflicts2) { - return STRONGLY_LESS; - } else { - // compare number of crossings for both variants - int crossings1 = countCrossings(this.targetPosis, other.getStart(), other.getEnd()) - + countCrossings(other.sourcePosis, this.getStart(), this.getEnd()); - int crossings2 = countCrossings(other.targetPosis, this.getStart(), this.getEnd()) - + countCrossings(this.sourcePosis, other.getStart(), other.getEnd()); - return crossings1 > crossings2 ? 1 : (crossings1 < crossings2 ? -1 : 0); - } - } - - /** - * {@inheritDoc} - */ - @Override - public boolean equals(final Object other) { - if (other instanceof TopoRoutingSlot) { - return this.compareTo((TopoRoutingSlot) other) == 0; - } else { - return false; - } - } - - /** - * {@inheritDoc} - */ - @Override - public int hashCode() { - return sourcePosis.hashCode() ^ targetPosis.hashCode() ^ Float.valueOf(getStart()).hashCode() - ^ Float.valueOf(getEnd()).hashCode(); - } - } - - /** factor for the minimal distance value for edge spacing. */ - private static final float EDGE_DIST_FACT = 0.25f; - - /** map of layer elements to their corresponding routing slots. */ - private Map slotMap = new LinkedHashMap(); - /** minimal distance for edge spacing. */ - private float edgeSpacing; - /** next dfs number for cycle breaking. */ - private int nextDfs; - - /** - * {@inheritDoc} - */ - @Override - public void reset() { - super.reset(); - slotMap.clear(); - } - - /** - * {@inheritDoc} - */ - public int placeEdges(final Layer layer, final float minDist) { - getMonitor().begin("Edge routing (layer " + layer.getRank() + ")", 1); - Direction layoutDirection = layer.getLayeredGraph().getLayoutDirection(); - this.edgeSpacing = minDist * EDGE_DIST_FACT; - - // determine number of outgoing connections for each port - Map outgoing = new HashMap(); - for (LayerElement element : layer.getElements()) { - // count outgoing connections - for (LayerConnection connection : element.getOutgoingConnections()) { - Object key = connection.getSourcePort(); - if (key == null) { - key = element; - } - Integer value = outgoing.get(key); - if (value == null) { - outgoing.put(key, Integer.valueOf(1)); - } else { - outgoing.put(key, Integer.valueOf(value.intValue() + 1)); - } - } - } - - // create routing slots for each port - for (LayerElement element : layer.getElements()) { - for (LayerConnection connection : element.getOutgoingConnections()) { - // choose source or target port for routing - Object key = connection.getSourcePort(); - if (key == null) { - key = element; - } - Integer sourceValue = outgoing.get(key); - if (sourceValue == null || sourceValue.intValue() <= 1) { - key = connection.getTargetPort(); - if (key == null) { - key = connection.getTargetElement(); - } - } - - // determine source and target positions - float sourcePos = connection.calcSourcePos(minDist); - float targetPos = connection.calcTargetPos(minDist); - if (layer.getRank() == 0 && connection.getSourcePort() != null) { - PortSide placement = connection.getSourcePort().getData(KShapeLayout.class) - .getProperty(LayoutOptions.PORT_SIDE); - if (layoutDirection == Direction.DOWN) { - if (placement == PortSide.WEST) { - sourcePos = 0.0f; - } else if (placement == PortSide.EAST) { - sourcePos = layer.getCrosswiseDim(); - } else if (placement == PortSide.SOUTH) { - sourcePos = layer.getCrosswiseDim(); - } - } else { - if (placement == PortSide.NORTH) { - sourcePos = 0.0f; - } else if (placement == PortSide.SOUTH) { - sourcePos = layer.getCrosswiseDim(); - } else if (placement == PortSide.EAST) { - sourcePos = layer.getCrosswiseDim(); - } - } - } else if (layer.getHeight() == 1 && connection.getTargetPort() != null) { - PortSide placement = connection.getTargetPort().getData(KShapeLayout.class) - .getProperty(LayoutOptions.PORT_SIDE); - if (layoutDirection == Direction.DOWN) { - if (placement == PortSide.WEST) { - targetPos = 0.0f; - } else if (placement == PortSide.EAST) { - targetPos = layer.getCrosswiseDim(); - } else if (placement == PortSide.NORTH) { - targetPos = layer.getCrosswiseDim(); - } - } else { - if (placement == PortSide.NORTH) { - targetPos = 0.0f; - } else if (placement == PortSide.SOUTH) { - targetPos = layer.getCrosswiseDim(); - } else if (placement == PortSide.WEST) { - targetPos = layer.getCrosswiseDim(); - } - } - } - float startPos = Math.min(sourcePos, targetPos); - float endPos = Math.max(sourcePos, targetPos); - - // get routing slot and insert connection area - TopoRoutingSlot slot = (TopoRoutingSlot) slotMap.get(key); - if (slot == null) { - slot = new TopoRoutingSlot(); - slot.setStart(startPos); - slot.setEnd(endPos); - slot.sourcePosis.add(Float.valueOf(sourcePos)); - slot.targetPosis.add(Float.valueOf(targetPos)); - slotMap.put(key, slot); - } else { - slot.setStart(Math.min(slot.getStart(), startPos)); - slot.setEnd(Math.max(slot.getEnd(), endPos)); - insertSorted(slot.sourcePosis, sourcePos); - insertSorted(slot.targetPosis, targetPos); - } - } - } - - // create links for the slot ordering graph - List slots = new LinkedList(slotMap.values()); - ListIterator slotIter1 = slots.listIterator(); - while (slotIter1.hasNext()) { - TopoRoutingSlot slot1 = (TopoRoutingSlot) slotIter1.next(); - ListIterator slotIter2 = slots.listIterator(slotIter1.nextIndex()); - while (slotIter2.hasNext()) { - TopoRoutingSlot slot2 = (TopoRoutingSlot) slotIter2.next(); - int rel = slot1.compareTo(slot2); - if (rel < 0) { - slot1.outgoing.add(new Pair(slot2, Boolean - .valueOf(rel == STRONGLY_LESS))); - slot2.incomingCount++; - } else if (rel > 0) { - slot2.outgoing.add(new Pair(slot1, Boolean - .valueOf(rel == STRONGLY_GREATER))); - slot1.incomingCount++; - } - } - } - - // break cycles in the slot ordering graph - LinkedList sources = new LinkedList(); - nextDfs = 1; - for (RoutingSlot slot : slots) { - TopoRoutingSlot topoSlot = (TopoRoutingSlot) slot; - breakCycles(topoSlot); - if (topoSlot.incomingCount == 0) { - sources.add(topoSlot); - } - } - - // assign ranks to all routing slots - int slotRanks = 0; - List> routingLayers = new LinkedList>(); - while (!sources.isEmpty()) { - TopoRoutingSlot source = sources.removeFirst(); - // find a proper rank for the current slot - int rank = routingLayers.size(); - ListIterator> routingLayerIter = routingLayers - .listIterator(routingLayers.size()); - List lastLayer = null; - while (routingLayerIter.hasPrevious()) { - List routingLayer = routingLayerIter.previous(); - boolean feasible = true; - for (RoutingSlot layerSlot : routingLayer) { - if (source.getStart() < layerSlot.getEnd() + edgeSpacing - && source.getEnd() > layerSlot.getStart() - edgeSpacing) { - feasible = false; - break; - } - } - if (!feasible) { - break; - } - lastLayer = routingLayer; - rank--; - } - if (lastLayer != null) { - source.setRank(rank); - lastLayer.add(source); - } else { - source.setRank(routingLayers.size()); - List routingLayer = new LinkedList(); - routingLayer.add(source); - routingLayers.add(routingLayer); - slotRanks++; - } - // update all outgoing links - for (Pair outgoingSlot : source.outgoing) { - outgoingSlot.getFirst().incomingCount--; - if (outgoingSlot.getFirst().incomingCount == 0) { - sources.addLast(outgoingSlot.getFirst()); - } - } - } - - getMonitor().done(); - return slotRanks; - } - - /** - * {@inheritDoc} - */ - public Map getSlotMap() { - return slotMap; - } - - /** - * Inserts a given value into a sorted list. - * - * @param list sorted list - * @param value value to insert - */ - private void insertSorted(final List list, final float value) { - ListIterator listIter = list.listIterator(); - while (listIter.hasNext()) { - float next = listIter.next().floatValue(); - if (next == value) { - return; - } else if (next > value) { - listIter.previous(); - break; - } - } - listIter.add(Float.valueOf(value)); - } - - /** - * Counts the number of crossings for a given list of positions. - * - * @param posis sorted list of positions - * @param start start of the critical area - * @param end end of the critical area - * @return number of positions in the critical area - */ - private int countCrossings(final List posis, final float start, final float end) { - int crossings = 0; - for (float pos : posis) { - if (pos > end) { - break; - } else if (pos >= start) { - crossings++; - } - } - return crossings; - } - - /** - * Counts the number of conflicts for the given lists of positions. - * - * @param posis1 sorted list of positions - * @param posis2 sorted list of positions - * @return number of positions that overlap - */ - private int countConflicts(final List posis1, final List posis2) { - int conflicts = 0; - if (!posis1.isEmpty() && !posis2.isEmpty()) { - Iterator iter1 = posis1.iterator(); - Iterator iter2 = posis2.iterator(); - float pos1 = iter1.next(); - float pos2 = iter2.next(); - boolean hasMore = true; - do { - if (pos1 > pos2 - edgeSpacing && pos1 < pos2 + edgeSpacing) { - conflicts++; - } - if (pos1 <= pos2 && iter1.hasNext()) { - pos1 = iter1.next(); - } else if (pos2 <= pos1 && iter2.hasNext()) { - pos2 = iter2.next(); - } else { - hasMore = false; - } - } while (hasMore); - } - return conflicts; - } - - /** - * Breaks cycles starting with the given slot. A DFS is performed, and back - * edges are removed if they are weak links. Otherwise a weak link is - * fetched and removed from the cycle. - * - * @param slot starting slot - * @return the highest DFS number of a slot found through a back edge, if - * that cycle could not be broken yet, or 0 otherwise - */ - private int breakCycles(final TopoRoutingSlot slot) { - int result = 0; - if (slot.visit < 0) { - slot.visit = nextDfs++; - ListIterator> slotIter = slot.outgoing.listIterator(); - while (slotIter.hasNext()) { - Pair outgoingSlot = slotIter.next(); - if (outgoingSlot.getFirst().visit > 0) { - if (outgoingSlot.getSecond().booleanValue()) { - // found a cycle through a strong link, update result - result = Math.max(result, outgoingSlot.getFirst().visit); - } else { - // found a cycle through a weak link, break it - slotIter.remove(); - outgoingSlot.getFirst().incomingCount--; - } - } else { - // follow the link - int outgoingRes = breakCycles(outgoingSlot.getFirst()); - if (outgoingRes > 0) { - if (outgoingRes == slot.visit || !outgoingSlot.getSecond().booleanValue()) { - // the link must be removed to break a cycle - slotIter.remove(); - outgoingSlot.getFirst().incomingCount--; - } else { - // the cycle can't be broken here, update result - result = Math.max(result, outgoingRes); - } - } - } - } - slot.visit = 0; - // temporarily store the result in the slot rank field - slot.setRank(result); - } else { - result = slot.getRank(); - } - return result; - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/package-info.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/package-info.java (revision d64f8376ecb2f5ba7914d76004fc6003b9ffb76c) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/impl/package-info.java (revision 0) @@ -1,18 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ - -/** - * Implementation of the hierarchical dataflow layout algorithm. - */ -package de.cau.cs.kieler.klodd.hierarchical.impl; Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/ICrossingReducer.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/ICrossingReducer.java (revision e40423edcc5feed14a967696da575e26a251c7db) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/ICrossingReducer.java (revision 0) @@ -1,35 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2008 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.modules; - -import de.cau.cs.kieler.core.alg.IAlgorithm; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayeredGraph; - -/** - * Interface for algorithms that reduce crossings in a layered graph. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public interface ICrossingReducer extends IAlgorithm { - - /** - * Reduces the number of crossings in a given layered directed graph by - * changing the order of nodes in each layer. - * - * @param layeredGraph layered graph to process - */ - void reduceCrossings(LayeredGraph layeredGraph); - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/IEdgeRouter.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/IEdgeRouter.java (revision e40423edcc5feed14a967696da575e26a251c7db) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/IEdgeRouter.java (revision 0) @@ -1,36 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2008 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.modules; - -import de.cau.cs.kieler.core.alg.IAlgorithm; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayeredGraph; - -/** - * Interface for algorithms that route edges in a layered graph. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public interface IEdgeRouter extends IAlgorithm { - - /** - * Route the edges of the given layered graph. - * - * @param layeredGraph layered graph to process - * @param objSpacing minimal distance between two edges - * @param borderSpacing spacing to the border - */ - void routeEdges(LayeredGraph layeredGraph, float objSpacing, float borderSpacing); - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/ILayerAssigner.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/ILayerAssigner.java (revision 8f1d84ae1efad2f1032a0e8a3f89852c58b82c7b) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/ILayerAssigner.java (revision 0) @@ -1,44 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2008 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.modules; - -import de.cau.cs.kieler.core.alg.IAlgorithm; -import de.cau.cs.kieler.core.kgraph.KNode; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayeredGraph; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimGraph; - -/** - * Interface for algorithms that assign layers to each node of a graph. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public interface ILayerAssigner extends IAlgorithm { - - /** - * Create a layered graph and assign layers to each node. The input ports - * must be put into the first layer (rank == 0), the output ports into the - * last layer (height == 0). - * - * @param slimGraph graph structure that contains no directed cycles - * @param parentNode the parent layout node - * @param objSpacing the minimal distance between objects - * @param balanceOverSize indicates whether node balancing has priority over - * diagram size - * @return a layered graph - */ - LayeredGraph assignLayers(KSlimGraph slimGraph, KNode parentNode, - float objSpacing, boolean balanceOverSize); - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/ILayerwiseEdgePlacer.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/ILayerwiseEdgePlacer.java (revision e40423edcc5feed14a967696da575e26a251c7db) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/ILayerwiseEdgePlacer.java (revision 0) @@ -1,48 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2008 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.modules; - -import java.util.Map; - -import de.cau.cs.kieler.core.alg.IAlgorithm; -import de.cau.cs.kieler.klodd.hierarchical.structures.Layer; -import de.cau.cs.kieler.klodd.hierarchical.structures.RoutingSlot; - -/** - * Interface for algorithms that calculate routing slots for connections going - * from a layer to the subsequent one. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public interface ILayerwiseEdgePlacer extends IAlgorithm { - - /** - * Determines a placement for each outgoing edge of the given layer. - * - * @param layer layer to process - * @param minDist minimal distance between elements - * @return number of assigned slot ranks - */ - int placeEdges(Layer layer, float minDist); - - /** - * Returns the map of layer elements to their corresponding routing slots - * that was constructed during the last run of placeEdges. - * - * @return the slot map - */ - Map getSlotMap(); - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/INodePlacer.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/INodePlacer.java (revision e40423edcc5feed14a967696da575e26a251c7db) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/INodePlacer.java (revision 0) @@ -1,40 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2008 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.modules; - -import de.cau.cs.kieler.core.alg.IAlgorithm; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayeredGraph; - -/** - * Interface for algorithms that determine a placement for each node in a - * layered graph. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public interface INodePlacer extends IAlgorithm { - - /** - * Determine a placement for each node in the given layered graph. - * - * @param layeredGraph layered graph to process - * @param objSpacing minimal distance between two nodes or edges in each layer - * @param borderSpacing spacing to the border - * @param balanceOverSize indicates whether node balancing has priority over - * diagram size - */ - void placeNodes(LayeredGraph layeredGraph, float objSpacing, float borderSpacing, - boolean balanceOverSize); - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/INodewiseEdgePlacer.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/INodewiseEdgePlacer.java (revision e40423edcc5feed14a967696da575e26a251c7db) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/INodewiseEdgePlacer.java (revision 0) @@ -1,36 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2008 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.modules; - -import de.cau.cs.kieler.core.alg.IAlgorithm; -import de.cau.cs.kieler.klodd.hierarchical.structures.LayeredGraph; - -/** - * Interface for algorithms that calculate routing slots for connections - * starting and ending at regular nodes. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public interface INodewiseEdgePlacer extends IAlgorithm { - - /** - * Determine placement for all edges starting or ending at regular nodes of - * the given layered graph. - * - * @param layeredGraph the layered graph to process - */ - void placeEdges(LayeredGraph layeredGraph); - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/ISingleLayerCrossingReducer.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/ISingleLayerCrossingReducer.java (revision e40423edcc5feed14a967696da575e26a251c7db) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/ISingleLayerCrossingReducer.java (revision 0) @@ -1,47 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2008 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.modules; - -import de.cau.cs.kieler.core.alg.IAlgorithm; -import de.cau.cs.kieler.klodd.hierarchical.structures.Layer; - -/** - * Interface for algorithms that offer heuristics for the 2-layer and 3-layer - * crossing reduction problem. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public interface ISingleLayerCrossingReducer extends IAlgorithm { - - /** - * Reduce crossings by changing the order of nodes in the given layer. Only - * one other layer is considered for crossings reduction. - * - * @param layer layer to be ordered - * @param forward if true, connections go to the given layer, else from the - * given layer - */ - void reduceCrossings(Layer layer, boolean forward); - - /** - * Reduce crossings by changing the order of nodes in the given layer. Both - * the preceding and the succeeding layers are considered for crossings - * reduction. - * - * @param layer layer to be ordered - */ - void reduceCrossings(Layer layer); - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/package-info.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/package-info.java (revision d64f8376ecb2f5ba7914d76004fc6003b9ffb76c) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/modules/package-info.java (revision 0) @@ -1,20 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ - -/** - * Definition of the different modules used by the hierarchical dataflow - * layout algorithm. These interface definitions follow the strategy - * design pattern to separate algorithm modules from their implementation. - */ -package de.cau.cs.kieler.klodd.hierarchical.modules; Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/package-info.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/package-info.java (revision d64f8376ecb2f5ba7914d76004fc6003b9ffb76c) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/package-info.java (revision 0) @@ -1,18 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ - -/** - * Base package of the hierarchical dataflow layout algorithm. - */ -package de.cau.cs.kieler.klodd.hierarchical; Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/ElementLoop.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/ElementLoop.java (revision 107e83a06604848b72d0e4cd9ae3bc84d786d0db) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/ElementLoop.java (revision 0) @@ -1,212 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2008 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.structures; - -import java.util.LinkedList; -import java.util.List; - -import de.cau.cs.kieler.core.kgraph.KEdge; -import de.cau.cs.kieler.core.kgraph.KPort; -import de.cau.cs.kieler.kiml.klayoutdata.KEdgeLayout; -import de.cau.cs.kieler.kiml.klayoutdata.KLayoutDataFactory; -import de.cau.cs.kieler.kiml.klayoutdata.KPoint; -import de.cau.cs.kieler.kiml.klayoutdata.KShapeLayout; -import de.cau.cs.kieler.kiml.options.PortSide; - -/** - * Loop over a single layer element in a layered graph. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class ElementLoop { - - /** routing position at north side. */ - private int northRoutePos = 0; - /** routing position at east side. */ - private int eastRoutePos = 0; - /** routing position at south side. */ - private int southRoutePos = 0; - /** routing position at west side. */ - private int westRoutePos = 0; - /** list of bend points of this connection. */ - private List bendPoints = new LinkedList(); - /** the contained edge object. */ - private KEdge edge; - /** the layer element. */ - private LayerElement element; - /** the source port. */ - private KPort sourcePort; - /** the target port. */ - private KPort targetPort; - - /** - * Creates an element loop with given source and target port. - * - * @param theedge the edge that is to be contained in this element loop - * @param elem the layer element of this loop - * @param thesourcePort the source port - * @param thetargetPort the target port - */ - public ElementLoop(final KEdge theedge, final LayerElement elem, final KPort thesourcePort, - final KPort thetargetPort) { - this.edge = theedge; - this.element = elem; - this.sourcePort = thesourcePort; - this.targetPort = thetargetPort; - theedge.getData(KEdgeLayout.class).getBendPoints().clear(); - } - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - return "[" + element.toString() + "] > [" + element.toString() + "]"; - } - - /** - * Gets the source port of this element loop. - * - * @return the source port - */ - public KPort getSourcePort() { - return sourcePort; - } - - /** - * Gets the target port of this element loop. - * - * @return the target port - */ - public KPort getTargetPort() { - return targetPort; - } - - /** - * Applies the layout of this element loop to the contained edge. - * - * @param offset offset to be added to each bend point - */ - public void applyLayout(final KPoint offset) { - KShapeLayout sourcePortLayout = sourcePort.getData(KShapeLayout.class); - KShapeLayout targetPortLayout = targetPort.getData(KShapeLayout.class); - KEdgeLayout edgeLayout = edge.getData(KEdgeLayout.class); - - // set bend points - for (KPoint point : bendPoints) { - point.setX(point.getX() + offset.getX()); - point.setY(point.getY() + offset.getY()); - edgeLayout.getBendPoints().add(point); - } - - // set start and end points - float xbase = element.getPosition().getX() + element.getPosOffset().getX(); - float ybase = element.getPosition().getY() + element.getPosOffset().getY(); - if (sourcePort != null) { - KPoint point = KLayoutDataFactory.eINSTANCE.createKPoint(); - float sourcePortWidth = sourcePortLayout.getWidth(); - float sourcePortHeight = sourcePortLayout.getHeight(); - point.setX(sourcePortLayout.getXpos() + sourcePortWidth / 2 + xbase); - point.setY(sourcePortLayout.getYpos() + sourcePortHeight / 2 + ybase); - alignEndpoint(point, edgeLayout.getBendPoints().get(0), sourcePortWidth, sourcePortHeight); - edgeLayout.setSourcePoint(point); - } - if (targetPort != null) { - KPoint point = KLayoutDataFactory.eINSTANCE.createKPoint(); - float targetPortWidth = targetPortLayout.getWidth(); - float targetPortHeight = targetPortLayout.getHeight(); - point.setX(targetPortLayout.getXpos() + targetPortWidth / 2 + xbase); - point.setY(targetPortLayout.getYpos() + targetPortHeight / 2 + ybase); - alignEndpoint(point, edgeLayout.getBendPoints().get(edgeLayout.getBendPoints().size() - 1), - targetPortWidth, targetPortHeight); - edgeLayout.setTargetPoint(point); - } - } - - /** - * Adds or subtracts the width or height of the given endpoint size, - * depending on the relative position of the next point. - * - * @param endpoint endpoint to align - * @param next next point on the edge - * @param width width of the endpoint object - * @param height height of the endpoint object - */ - private void alignEndpoint(final KPoint endpoint, final KPoint next, final float width, - final float height) { - if (next.getX() > endpoint.getX()) { - endpoint.setX(endpoint.getX() + width / 2); - } else if (next.getY() > endpoint.getY()) { - endpoint.setY(endpoint.getY() + height / 2); - } else if (next.getX() < endpoint.getX()) { - endpoint.setX(endpoint.getX() - width / 2); - } else if (next.getY() < endpoint.getY()) { - endpoint.setY(endpoint.getY() - height / 2); - } - } - - /** - * Returns the bendPoints. - * - * @return the bendPoints - */ - public List getBendPoints() { - return bendPoints; - } - - /** - * Sets the route position for a specific side. - * - * @param routePos the route position to set - * @param side the side for the route position - */ - public void setRoutePos(final int routePos, final PortSide side) { - switch (side) { - case NORTH: - this.northRoutePos = routePos; - break; - case EAST: - this.eastRoutePos = routePos; - break; - case SOUTH: - this.southRoutePos = routePos; - break; - case WEST: - this.westRoutePos = routePos; - break; - } - } - - /** - * Gets the route position for a specific side. - * - * @param side the side for the route position - * @return the route position for the given side - */ - public int getRoutePos(final PortSide side) { - switch (side) { - case NORTH: - return northRoutePos; - case EAST: - return eastRoutePos; - case SOUTH: - return southRoutePos; - case WEST: - return westRoutePos; - } - return 0; - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/Layer.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/Layer.java (revision e0bd6314837428e0aa79b885fcaab309f0101b0b) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/Layer.java (revision 0) @@ -1,306 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2008 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.structures; - -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.LinkedList; - -import de.cau.cs.kieler.core.kgraph.KGraphElement; -import de.cau.cs.kieler.core.kgraph.KPort; -import de.cau.cs.kieler.kiml.klayoutdata.KShapeLayout; -import de.cau.cs.kieler.kiml.options.LayoutOptions; -import de.cau.cs.kieler.kiml.util.KimlUtil; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimNode; - -/** - * A single Layer used in a layered graph. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class Layer { - - /** value to use if the rank is undefined. */ - public static final int UNDEF_RANK = -1; - /** value to use if the height is undefined. */ - public static final int UNDEF_HEIGHT = -1; - - /** the rank of this layer. */ - private int rank; - /** the height of this layer. */ - private int height; - /** lengthwise position of this layer. */ - private float lengthwisePos = 0.0f; - /** crosswise dimension of this layer. */ - private float crosswiseDim = 0.0f; - /** lengthwise dimension of this layer. */ - private float lengthwiseDim = 0.0f; - /** next layer in the layered graph. */ - private Layer next; - /** the containing layered graph. */ - private LayeredGraph layeredGraph; - /** list of elements in this layer. */ - private List elements = new LinkedList(); - - /** - * Creates a new layer with given rank and height. - * - * @param therank the rank, may be UNDEF_RANK - * @param theheight the height, may be UNDEF_HEIGHT - * @param thelayeredGraph layered graph in which the layer is created - */ - public Layer(final int therank, final int theheight, final LayeredGraph thelayeredGraph) { - this.rank = therank; - this.height = theheight; - this.layeredGraph = thelayeredGraph; - } - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - return elements.toString(); - } - - /** - * Puts an object into this layer. - * - * @param obj the element object - * @param kNode the corresponding node in the acyclic KIELER graph - * @return the new layer element - */ - public LayerElement put(final KGraphElement obj, final KSlimNode kNode) { - LayerElement element = new LayerElement(obj, this, kNode); - elements.add(element); - return element; - } - - /** - * Sets the lengthwise position of this layer and all layer elements. - * - * @param layerPos starting lengthwise position of this layer - * @param minDist minimal distance between nodes and connections - */ - public void layoutElements(final float layerPos, final float minDist) { - lengthwisePos = layerPos; - if (rank > 0 && height > 0) { - for (LayerElement element : elements) { - float sideSpace; - if (element.getIncomingConnections().isEmpty() - && !element.getOutgoingConnections().isEmpty()) { - sideSpace = (lengthwiseDim - element.getTotalLengthwiseDim(minDist)); - } else if (element.getOutgoingConnections().isEmpty() - && !element.getIncomingConnections().isEmpty()) { - sideSpace = 0; - } else { - sideSpace = (lengthwiseDim - element.getTotalLengthwiseDim(minDist)) / 2; - } - element.setLengthwisePos(lengthwisePos + sideSpace, minDist); - } - } - } - - /** - * Gets the elements of this layer. - * - * @return the layer elements - */ - public List getElements() { - return elements; - } - - /** - * Gets the layered graph. - * - * @return the layeredGraph - */ - public LayeredGraph getLayeredGraph() { - return layeredGraph; - } - - /** - * Sorts the elements in this layer and assigns them new rank values based - * on the ranks of contained ports. This method may only be called on - * external ports layers with either {@code rank == 0} or {@code height == 0}. - * - * @param newRanks if true new port ranks are determined for the contained ports - */ - public void sortByPorts(final boolean newRanks) { - boolean forward; - if (rank == 0) { - forward = true; - } else if (height == 0) { - forward = false; - } else { - throw new UnsupportedOperationException(); - } - - if (newRanks) { - // set port ranks according to current order in this layer - int portrank = 0; - for (LayerElement element : elements) { - KPort port = (KPort) element.getElemObj(); - port.getData(KShapeLayout.class).setProperty(LayoutOptions.PORT_RANK, - portrank++); - } - } - // sort elements according to port sides and ranks - final Comparator portComparator = new KimlUtil.PortComparator(forward, layeredGraph - .getLayoutDirection()); - Collections.sort(elements, new Comparator() { - public int compare(final LayerElement elem1, final LayerElement elem2) { - KPort port1 = (KPort) elem1.getElemObj(); - KPort port2 = (KPort) elem2.getElemObj(); - return portComparator.compare(port1, port2); - } - }); - if (newRanks) { - // set port ranks according to new sorted order - int portrank = 0; - for (LayerElement element : elements) { - KPort port = (KPort) element.getElemObj(); - port.getData(KShapeLayout.class).setProperty(LayoutOptions.PORT_RANK, - portrank++); - } - } - - // calculate concrete rank values for the layer elements - calcElemRanks(); - } - - /** - * Calculates the element rank of each element in this layer. The rank is - * induced by the order of elements in the internal list and the rank width - * of each element. - */ - public void calcElemRanks() { - int elemrank = 0; - for (LayerElement element : elements) { - element.setRank(elemrank); - elemrank += element.getRankWidth(); - } - } - - /** - * Sets the rank. - * - * @param therank the rank to set - */ - public void setRank(final int therank) { - this.rank = therank; - } - - /** - * Returns the rank. - * - * @return the rank - */ - public int getRank() { - return rank; - } - - /** - * Sets the height. - * - * @param theheight the height to set - */ - public void setHeight(final int theheight) { - this.height = theheight; - } - - /** - * Returns the height. - * - * @return the height - */ - public int getHeight() { - return height; - } - - /** - * Sets the lengthwisePos. - * - * @param thelengthwisePos the lengthwisePos to set - */ - public void setLengthwisePos(final float thelengthwisePos) { - this.lengthwisePos = thelengthwisePos; - } - - /** - * Returns the lengthwisePos. - * - * @return the lengthwisePos - */ - public float getLengthwisePos() { - return lengthwisePos; - } - - /** - * Sets the crosswiseDim. - * - * @param thecrosswiseDim the crosswiseDim to set - */ - public void setCrosswiseDim(final float thecrosswiseDim) { - this.crosswiseDim = thecrosswiseDim; - } - - /** - * Returns the crosswiseDim. - * - * @return the crosswiseDim - */ - public float getCrosswiseDim() { - return crosswiseDim; - } - - /** - * Sets the lengthwiseDim. - * - * @param thelengthwiseDim the lengthwiseDim to set - */ - public void setLengthwiseDim(final float thelengthwiseDim) { - this.lengthwiseDim = thelengthwiseDim; - } - - /** - * Returns the lengthwiseDim. - * - * @return the lengthwiseDim - */ - public float getLengthwiseDim() { - return lengthwiseDim; - } - - /** - * Sets the next. - * - * @param thenext the next to set - */ - public void setNext(final Layer thenext) { - this.next = thenext; - } - - /** - * Returns the next. - * - * @return the next - */ - public Layer getNext() { - return next; - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/LayerConnection.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/LayerConnection.java (revision a732291a21c31eab15b25e3bdb11c89af3881a57) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/LayerConnection.java (revision 0) @@ -1,446 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2008 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.structures; - -import java.util.LinkedList; -import java.util.List; - -import de.cau.cs.kieler.core.kgraph.KEdge; -import de.cau.cs.kieler.core.kgraph.KNode; -import de.cau.cs.kieler.core.kgraph.KPort; -import de.cau.cs.kieler.kiml.klayoutdata.KEdgeLayout; -import de.cau.cs.kieler.kiml.klayoutdata.KInsets; -import de.cau.cs.kieler.kiml.klayoutdata.KLayoutDataFactory; -import de.cau.cs.kieler.kiml.klayoutdata.KPoint; -import de.cau.cs.kieler.kiml.klayoutdata.KShapeLayout; -import de.cau.cs.kieler.kiml.options.Direction; -import de.cau.cs.kieler.kiml.options.LayoutOptions; -import de.cau.cs.kieler.kiml.options.PortSide; - -/** - * Connection between two layer elements in a layered graph. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class LayerConnection { - - /** side routing position at the source of this connection. */ - private int sourceSidePos = 0; - /** side routing position at the target of this connection. */ - private int targetSidePos = 0; - /** back routing position at the source of this connection. */ - private int sourceBackPos = 0; - /** front routing position at the target of this connection. */ - private int targetFrontPos = 0; - /** crosswise position of the connection anchor at source. */ - private float sourceAnchorPos = 0.0f; - /** crosswise position of the connection anchor at target. */ - private float targetAnchorPos = 0.0f; - /** list of bend points of this connection. */ - private List bendPoints = new LinkedList(); - /** the contained edge object. */ - private KEdge edge; - /** the source element. */ - private LayerElement sourceElement; - /** the source port. */ - private KPort sourcePort; - /** the target element. */ - private LayerElement targetElement; - /** the target port. */ - private KPort targetPort; - - /** - * Creates a layer connection with given source and target. - * - * @param theedge the edge that is to be contained in this layer connection - * @param sourceElem the source element - * @param thesourcePort the source port - * @param targetElem the target element - * @param thetargetPort the target port - */ - public LayerConnection(final KEdge theedge, final LayerElement sourceElem, - final KPort thesourcePort, final LayerElement targetElem, final KPort thetargetPort) { - this.edge = theedge; - this.sourceElement = sourceElem; - this.sourcePort = thesourcePort; - this.targetElement = targetElem; - this.targetPort = thetargetPort; - theedge.getData(KEdgeLayout.class).getBendPoints().clear(); - } - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - return "[" + sourceElement.toString() + "] > [" + targetElement.toString() + "]"; - } - - /** - * Applies the layout of this layer connection to the contained edge. - * - * @param offset offset to be added to each bend point - * @param insets insets of the containing parent layout node - */ - public void applyLayout(final KPoint offset, final KInsets insets) { - LayeredGraph layeredGraph = sourceElement.getLayer().getLayeredGraph(); - Direction layoutDirection = layeredGraph.getLayoutDirection(); - KShapeLayout sourcePortLayout = (sourcePort == null ? null - : sourcePort.getData(KShapeLayout.class)); - KShapeLayout targetPortLayout = (targetPort == null ? null - : targetPort.getData(KShapeLayout.class)); - KEdgeLayout edgeLayout = edge.getData(KEdgeLayout.class); - - // set bend points - for (KPoint point : bendPoints) { - point.setX(point.getX() + offset.getX()); - point.setY(point.getY() + offset.getY()); - edgeLayout.getBendPoints().add(point); - } - - // calculate position of source point - KPoint sourcePoint = KLayoutDataFactory.eINSTANCE.createKPoint(); - if (sourcePort != null) { - if (sourcePort.getNode() == layeredGraph.getParentNode()) { - sourcePoint.setX(sourceElement.getPosition().getX() + sourcePortLayout.getWidth() / 2); - sourcePoint.setY(sourceElement.getPosition().getY() + sourcePortLayout.getHeight() / 2); - float portOffset = sourcePortLayout.getProperty(LayoutOptions.OFFSET); - toExternalEndpoint(sourcePoint, sourcePortLayout.getProperty(LayoutOptions.PORT_SIDE), - portOffset, insets); - } else { - sourcePoint.setX(sourcePortLayout.getXpos() + sourcePortLayout.getWidth() / 2 - + sourceElement.getPosition().getX() + sourceElement.getPosOffset().getX()); - sourcePoint.setY(sourcePortLayout.getYpos() + sourcePortLayout.getHeight() / 2 - + sourceElement.getPosition().getY() + sourceElement.getPosOffset().getY()); - } - } else if (sourceElement.getElemObj() instanceof KNode) { - KNode sourceNode = (KNode) sourceElement.getElemObj(); - KShapeLayout sourceLayout = sourceNode.getData(KShapeLayout.class); - sourcePoint.setX(sourceElement.getPosition().getX() - + sourceElement.getPosOffset().getX() - + (layoutDirection == Direction.DOWN ? sourceLayout.getWidth() / 2 - : sourceLayout.getWidth())); - sourcePoint.setY(sourceElement.getPosition().getY() - + sourceElement.getPosOffset().getY() - + (layoutDirection == Direction.DOWN ? sourceLayout.getHeight() - : sourceLayout.getHeight() / 2)); - edgeLayout.setSourcePoint(sourcePoint); - } - - // calculate position of target point - KPoint targetPoint = KLayoutDataFactory.eINSTANCE.createKPoint(); - if (targetPort != null) { - if (targetPort.getNode() == layeredGraph.getParentNode()) { - targetPoint.setX(targetElement.getPosition().getX() + targetPortLayout.getWidth() / 2); - targetPoint.setY(targetElement.getPosition().getY() + targetPortLayout.getHeight() / 2); - float portOffset = targetPortLayout.getProperty(LayoutOptions.OFFSET); - toExternalEndpoint(targetPoint, targetPortLayout.getProperty(LayoutOptions.PORT_SIDE), - portOffset, insets); - } else { - targetPoint.setX(targetPortLayout.getXpos() + targetPortLayout.getWidth() / 2 - + targetElement.getPosition().getX() + targetElement.getPosOffset().getX()); - targetPoint.setY(targetPortLayout.getYpos() + targetPortLayout.getHeight() / 2 - + targetElement.getPosition().getY() + targetElement.getPosOffset().getY()); - } - } else if (targetElement.getElemObj() instanceof KNode) { - KNode targetNode = (KNode) targetElement.getElemObj(); - KShapeLayout targetLayout = targetNode.getData(KShapeLayout.class); - targetPoint - .setX(targetElement.getPosition().getX() - + targetElement.getPosOffset().getX() - + (layoutDirection == Direction.DOWN ? targetLayout.getWidth() / 2 - : 0.0f)); - targetPoint - .setY(targetElement.getPosition().getY() - + targetElement.getPosOffset().getY() - + (layoutDirection == Direction.DOWN ? 0.0f : targetLayout - .getHeight() / 2)); - edgeLayout.setTargetPoint(targetPoint); - } - - // align the endpoints of the edge if they go to ports - if (sourcePort != null) { - alignEndpoint(sourcePoint, bendPoints.isEmpty() ? targetPoint : bendPoints.get(0), - sourcePortLayout.getWidth(), sourcePortLayout.getHeight()); - edgeLayout.setSourcePoint(sourcePoint); - } - - if (targetPort != null) { - alignEndpoint(targetPoint, bendPoints.isEmpty() ? sourcePoint : bendPoints.get(bendPoints - .size() - 1), targetPortLayout.getWidth(), targetPortLayout.getHeight()); - edgeLayout.setTargetPoint(targetPoint); - } - } - - /** - * Gets the source element. - * - * @return the sourceElement - */ - public LayerElement getSourceElement() { - return sourceElement; - } - - /** - * Gets the source port. - * - * @return the sourcePort - */ - public KPort getSourcePort() { - return sourcePort; - } - - /** - * Gets the target element. - * - * @return the targetElement - */ - public LayerElement getTargetElement() { - return targetElement; - } - - /** - * Gets the target port. - * - * @return the targetPort - */ - public KPort getTargetPort() { - return targetPort; - } - - /** - * Determines the source position of this edge from the current layout - * position. - * - * @param minDist minimal distance between elements - * @return position - */ - public float calcSourcePos(final float minDist) { - LayeredGraph layeredGraph = sourceElement.getLayer().getLayeredGraph(); - Direction layoutDirection = layeredGraph.getLayoutDirection(); - sourceAnchorPos = layoutDirection == Direction.DOWN ? sourceElement.getPosition() - .getX() : sourceElement.getPosition().getY(); - if (sourceSidePos == 0) { - if (sourcePort == null) { - // there is no source port, find appropriate anchor - sourceAnchorPos += layoutDirection == Direction.DOWN ? sourceElement - .getRealWidth() / 2 : sourceElement.getRealHeight() / 2; - } else { - // align the edge to the source port - KShapeLayout portLayout = sourcePort.getData(KShapeLayout.class); - sourceAnchorPos += layoutDirection == Direction.DOWN - ? portLayout.getWidth() / 2 : portLayout.getHeight() / 2; - if (sourcePort.getNode() != layeredGraph.getParentNode()) { - sourceAnchorPos += layoutDirection == Direction.DOWN ? portLayout - .getXpos() - + sourceElement.getPosOffset().getX() : portLayout.getYpos() - + sourceElement.getPosOffset().getY(); - } - } - } else if (sourceSidePos > 0) { - sourceAnchorPos += (layoutDirection == Direction.DOWN ? sourceElement - .getRealWidth() : sourceElement.getRealHeight()) - + sourceSidePos * minDist; - } else if (sourceSidePos < 0) { - sourceAnchorPos += sourceSidePos * minDist; - } - return sourceAnchorPos; - } - - /** - * Determines the target position of this edge from the current layout - * position. - * - * @param minDist minimal distance between elements - * @return position - */ - public float calcTargetPos(final float minDist) { - LayeredGraph layeredGraph = sourceElement.getLayer().getLayeredGraph(); - Direction layoutDirection = layeredGraph.getLayoutDirection(); - targetAnchorPos = layoutDirection == Direction.DOWN ? targetElement.getPosition() - .getX() : targetElement.getPosition().getY(); - if (getTargetSidePos() == 0) { - if (targetPort == null) { - // there is no source port, find appropriate anchor - targetAnchorPos += layoutDirection == Direction.DOWN ? targetElement - .getRealWidth() / 2 : targetElement.getRealHeight() / 2; - } else { - KShapeLayout portLayout = targetPort.getData(KShapeLayout.class); - targetAnchorPos += layoutDirection == Direction.DOWN - ? portLayout.getWidth() / 2 : portLayout.getHeight() / 2; - if (targetPort.getNode() != layeredGraph.getParentNode()) { - targetAnchorPos += layoutDirection == Direction.DOWN ? portLayout - .getXpos() - + targetElement.getPosOffset().getX() : portLayout.getYpos() - + targetElement.getPosOffset().getY(); - } - } - } else if (getTargetSidePos() > 0) { - targetAnchorPos += (layoutDirection == Direction.DOWN ? targetElement - .getRealWidth() : targetElement.getRealHeight()) - + getTargetSidePos() * minDist; - } else if (getTargetSidePos() < 0) { - targetAnchorPos += getTargetSidePos() * minDist; - } - return targetAnchorPos; - } - - /** - * Sets the proper position of an endpoint that goes to an external port. - * - * @param endpoint endpoint to align - * @param portSide side of external port used as endpoint - * @param portOffset additional offset of the port - */ - private void toExternalEndpoint(final KPoint endpoint, final PortSide portSide, - final float portOffset, final KInsets insets) { - switch (portSide) { - case NORTH: - endpoint.setY(endpoint.getY() - portOffset - insets.getTop()); - break; - case EAST: - endpoint.setX(endpoint.getX() + portOffset + insets.getRight()); - break; - case SOUTH: - endpoint.setY(endpoint.getY() + portOffset + insets.getBottom()); - break; - case WEST: - endpoint.setX(endpoint.getX() - portOffset - insets.getLeft()); - break; - } - } - - /** - * Adds or subtracts the width or height of the given endpoint size, - * depending on the relative position of the next point. - * - * @param endpoint endpoint to align - * @param next next point on the edge - * @param width width of the endpoint object - * @param height height of the endpoint object - */ - private void alignEndpoint(final KPoint endpoint, final KPoint next, final float width, - final float height) { - if (next.getX() > endpoint.getX()) { - endpoint.setX(endpoint.getX() + width / 2); - } else if (next.getY() > endpoint.getY()) { - endpoint.setY(endpoint.getY() + height / 2); - } else if (next.getX() < endpoint.getX()) { - endpoint.setX(endpoint.getX() - width / 2); - } else if (next.getY() < endpoint.getY()) { - endpoint.setY(endpoint.getY() - height / 2); - } - } - - /** - * Sets the source side position. - * - * @param thesourceSidePos the source side position to set - */ - public void setSourceSidePos(final int thesourceSidePos) { - this.sourceSidePos = thesourceSidePos; - } - - /** - * Returns the source side position. - * - * @return the source side position - */ - public int getSourceSidePos() { - return sourceSidePos; - } - - /** - * Sets the target side position. - * - * @param thetargetSidePos the target side position to set - */ - public void setTargetSidePos(final int thetargetSidePos) { - this.targetSidePos = thetargetSidePos; - } - - /** - * Returns the target side position. - * - * @return the target side position - */ - public int getTargetSidePos() { - return targetSidePos; - } - - /** - * Sets the source back position. - * - * @param thesourceBackPos the source back position to set - */ - public void setSourceBackPos(final int thesourceBackPos) { - this.sourceBackPos = thesourceBackPos; - } - - /** - * Returns the source back position. - * - * @return the source back position - */ - public int getSourceBackPos() { - return sourceBackPos; - } - - /** - * Sets the target front position. - * - * @param thetargetFrontPos the target front position to set - */ - public void setTargetFrontPos(final int thetargetFrontPos) { - this.targetFrontPos = thetargetFrontPos; - } - - /** - * Returns the target front position. - * - * @return the target front position - */ - public int getTargetFrontPos() { - return targetFrontPos; - } - - /** - * Returns the source anchor position. - * - * @return the source anchor position - */ - public float getSourceAnchorPos() { - return sourceAnchorPos; - } - - /** - * Returns the target anchor position. - * - * @return the target anchor position - */ - public float getTargetAnchorPos() { - return targetAnchorPos; - } - - /** - * Returns the bend points. - * - * @return the bend points - */ - public List getBendPoints() { - return bendPoints; - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/LayerElement.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/LayerElement.java (revision c6d39664cfb271f5286db0327ecaca0c47e77c8b) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/LayerElement.java (revision 0) @@ -1,1127 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2008 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.structures; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.Comparator; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import de.cau.cs.kieler.core.kgraph.KEdge; -import de.cau.cs.kieler.core.kgraph.KGraphElement; -import de.cau.cs.kieler.core.kgraph.KLabel; -import de.cau.cs.kieler.core.kgraph.KNode; -import de.cau.cs.kieler.core.kgraph.KPort; -import de.cau.cs.kieler.kiml.klayoutdata.KInsets; -import de.cau.cs.kieler.kiml.klayoutdata.KLayoutDataFactory; -import de.cau.cs.kieler.kiml.klayoutdata.KPoint; -import de.cau.cs.kieler.kiml.klayoutdata.KShapeLayout; -import de.cau.cs.kieler.kiml.options.Direction; -import de.cau.cs.kieler.kiml.options.LayoutOptions; -import de.cau.cs.kieler.kiml.options.PortConstraints; -import de.cau.cs.kieler.kiml.options.PortSide; -import de.cau.cs.kieler.kiml.util.KimlUtil; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimEdge; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimNode; - -/** - * A layer element representing a node or a long edge in the layered graph. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class LayerElement { - - /** value to use if the rank is undefined. */ - public static final int UNDEF_RANK = -1; - - /** rank of this element inside the containing layer. */ - private int rank = UNDEF_RANK; - /** linear segment containing this layer element. */ - private LinearSegment linearSegment = null; - /** the number of routing slot ranks on north side. */ - private int northRanks = 0; - /** the number of routing slot ranks on east side. */ - private int eastRanks = 0; - /** the number of routing slot ranks on south side. */ - private int southRanks = 0; - /** the number of routing slot ranks on west side. */ - private int westRanks = 0; - /** the element object. */ - private KGraphElement elemObj; - /** the containing layer. */ - private Layer layer; - /** the corresponding node in the acyclic KIELER graph. */ - private KSlimNode kNode; - /** port constraints for this layer element. */ - private PortConstraints portConstraints; - /** number of rank numbers consumed by this layer element. */ - private int rankWidth; - /** the new position that is determined for this layer element. */ - private KPoint position; - /** offset to be added to the determined position. */ - private KPoint posOffset; - /** the width of the contained object. */ - private float realWidth; - /** the height of the contained object. */ - private float realHeight; - /** the total crosswise dimension. */ - private float totalCrosswiseDim = -1.0f; - /** crosswise spacing to be left before the element. */ - private float preSpacingCross; - /** the total lengthwise dimension. */ - private float totalLengthwiseDim = -1.0f; - /** lengthwise spacing to be left before the element. */ - private float preSpacingLength; - /** the list of incoming layer connections. */ - private List incoming = new LinkedList(); - /** the list of outgoing layer connections. */ - private List outgoing = new LinkedList(); - /** the list of element loop. */ - private List loops = new LinkedList(); - /** map of ports to port ranks. */ - private Map portRanks = null; - /** ports on the north side. */ - private KPort[] northPorts; - /** ports on the east side. */ - private KPort[] eastPorts; - /** ports on the south side. */ - private KPort[] southPorts; - /** ports on the west side. */ - private KPort[] westPorts; - - /** - * Creates a layer element in an existing layer. - * - * @param obj the element object - * @param thelayer the containing layer - * @param thekNode the corresponding node in the acyclic KIELER graph - */ - public LayerElement(final KGraphElement obj, final Layer thelayer, final KSlimNode thekNode) { - this.elemObj = obj; - this.layer = thelayer; - this.kNode = thekNode; - this.position = KLayoutDataFactory.eINSTANCE.createKPoint(); - this.posOffset = KLayoutDataFactory.eINSTANCE.createKPoint(); - - if (obj instanceof KNode) { - // the layer element is a layout node - KNode node = (KNode) obj; - KShapeLayout nodeLayout = node.getData(KShapeLayout.class); - portConstraints = nodeLayout.getProperty(LayoutOptions.PORT_CONSTRAINTS); - rankWidth = Math.max(node.getPorts().size(), 1); - realWidth = nodeLayout.getWidth(); - realHeight = nodeLayout.getHeight(); - - // create port lists - List northPortList = new LinkedList(); - List eastPortList = new LinkedList(); - List southPortList = new LinkedList(); - List westPortList = new LinkedList(); - for (KPort port : node.getPorts()) { - PortSide portSide = port.getData(KShapeLayout.class) - .getProperty(LayoutOptions.PORT_SIDE); - switch (portSide) { - case NORTH: - northPortList.add(port); - break; - case EAST: - eastPortList.add(port); - break; - case SOUTH: - southPortList.add(port); - break; - case WEST: - westPortList.add(port); - } - } - KPort[] dummyArray = new KPort[0]; - northPorts = northPortList.toArray(dummyArray); - eastPorts = eastPortList.toArray(dummyArray); - southPorts = southPortList.toArray(dummyArray); - westPorts = westPortList.toArray(dummyArray); - if (portConstraints == PortConstraints.FIXED_POS - || portConstraints == PortConstraints.FIXED_ORDER) { - Comparator portComparator = new Comparator() { - public int compare(final KPort port1, final KPort port2) { - KShapeLayout layout1 = port1.getData(KShapeLayout.class); - KShapeLayout layout2 = port2.getData(KShapeLayout.class); - int rank1 = layout1.getProperty(LayoutOptions.PORT_RANK); - int rank2 = layout2.getProperty(LayoutOptions.PORT_RANK); - return rank1 - rank2; - } - }; - Arrays.sort(northPorts, portComparator); - Arrays.sort(eastPorts, portComparator); - Arrays.sort(southPorts, portComparator); - Arrays.sort(westPorts, portComparator); - } - } else if (obj instanceof KPort) { - // the layer element is a port - KPort port = (KPort) obj; - KShapeLayout shapeLayout = port.getData(KShapeLayout.class); - portConstraints = PortConstraints.FIXED_POS; - rankWidth = 1; - realWidth = shapeLayout.getWidth(); - realHeight = shapeLayout.getHeight(); - } else if (obj instanceof KEdge) { - // the layer element is a long edge - portConstraints = PortConstraints.FIXED_POS; - rankWidth = 1; - realWidth = 0.0f; - realHeight = 0.0f; - } else { - throw new IllegalArgumentException("Unknown object type received."); - } - } - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - if (elemObj instanceof KNode) { - KNode node = (KNode) elemObj; - String label = node.getLabels().get(0).getText(); - if (label != null && label.length() > 0) { - return label; - } else { - return "node:" + rank; - } - } else if (elemObj instanceof KPort) { - KPort port = (KPort) elemObj; - return "port:" + port.getLabels().get(0).getText(); - } else if (elemObj instanceof KEdge) { - KEdge edge = (KEdge) elemObj; - KNode source = edge.getSource(); - KNode target = edge.getTarget(); - if (source != null && target != null) { - return "(" + source.getLabels().get(0).getText() + ") > (" - + target.getLabels().get(0).getText() + ")"; - } else if (target != null) { - return "(" + edge.getSourcePort().getLabels().get(0).getText() + ") > (" - + target.getLabels().get(0).getText() + ")"; - } else if (source != null) { - return "(" + source.getLabels().get(0).getText() + ") > (" - + edge.getTargetPort().getLabels().get(0).getText() + ")"; - } else { - return "(" + edge.getSourcePort().getLabels().get(0).getText() + ") > (" - + edge.getTargetPort().getLabels().get(0).getText() + ")"; - } - } else { - return "element:" + rank; - } - } - - /** - * Get the containing layer. - * - * @return the layer - */ - public Layer getLayer() { - return layer; - } - - /** - * Set a new layer for this element. The element is added to the new layer. - * - * @param newLayer the new layer - */ - public void setLayer(final Layer newLayer) { - this.layer = newLayer; - newLayer.getElements().add(this); - } - - /** - * Gets the outgoing edges of the contained object. - * - * @return the list of outgoing edges, or null if the object is an edge - */ - public List getOutgoingEdges() { - if (kNode != null) { - LinkedList nonLoopEdges = new LinkedList(); - for (KSlimNode.IncEntry edgeEntry : kNode.getIncidence()) { - // ignore loops over a single node - if (edgeEntry.getType() == KSlimNode.IncEntry.Type.OUT - && edgeEntry.getEdge().getSource().getId() - != edgeEntry.getEdge().getTarget().getId()) { - nonLoopEdges.add(edgeEntry.getEdge()); - } - } - return nonLoopEdges; - } else { - return null; - } - } - - /** - * Adds a new cross-layer connection with given target. - * - * @param edge the edge between the two layout nodes - * @param target target layer element - */ - public void addOutgoing(final KEdge edge, final LayerElement target) { - addOutgoing(edge, target, null, null); - } - - /** - * Adds a new cross-layer connection with given target. - * - * @param edge the edge between the two layout nodes - * @param target target layer element - * @param sourcePort the source port - * @param targetPort the target port - */ - public void addOutgoing(final KEdge edge, final LayerElement target, final KPort sourcePort, - final KPort targetPort) { - LayerConnection connection = new LayerConnection(edge, this, sourcePort, target, targetPort); - this.outgoing.add(connection); - target.incoming.add(connection); - } - - /** - * Applies the layout of this layer element to the contained object and - * updates position information according to given offset values. - * - * @param offset offset to be added to this element's position - * @param insets insets of the containing parent layout node - */ - public void applyLayout(final KPoint offset, final KInsets insets) { - position.setX(position.getX() + offset.getX()); - position.setY(position.getY() + offset.getY()); - if (elemObj instanceof KNode) { - KShapeLayout shapeLayout = elemObj.getData(KShapeLayout.class); - shapeLayout.setXpos(position.getX() + posOffset.getX()); - shapeLayout.setYpos(position.getY() + posOffset.getY()); - } else if (elemObj instanceof KPort) { - KShapeLayout shapeLayout = elemObj.getData(KShapeLayout.class); - float portOffset = shapeLayout.getProperty(LayoutOptions.OFFSET); - switch (shapeLayout.getProperty(LayoutOptions.PORT_SIDE)) { - case NORTH: - if (layer.getLayeredGraph().getExternalPortConstraints() == PortConstraints.FIXED_POS) { - shapeLayout.setXpos(position.getX()); - } else { - shapeLayout.setXpos(position.getX() + insets.getLeft()); - } - shapeLayout.setYpos(position.getY() - portOffset); - break; - case EAST: - shapeLayout.setXpos(position.getX() + insets.getLeft() + insets.getRight() + portOffset); - if (layer.getLayeredGraph().getExternalPortConstraints() == PortConstraints.FIXED_POS) { - shapeLayout.setYpos(position.getY()); - } else { - shapeLayout.setYpos(position.getY() + insets.getTop()); - } - break; - case SOUTH: - if (layer.getLayeredGraph().getExternalPortConstraints() == PortConstraints.FIXED_POS) { - shapeLayout.setXpos(position.getX()); - } else { - shapeLayout.setXpos(position.getX() + insets.getLeft()); - } - shapeLayout.setYpos(position.getY() + insets.getTop() + insets.getBottom() + portOffset); - break; - case WEST: - shapeLayout.setXpos(position.getX() - portOffset); - if (layer.getLayeredGraph().getExternalPortConstraints() == PortConstraints.FIXED_POS) { - shapeLayout.setYpos(position.getY()); - } else { - shapeLayout.setYpos(position.getY() + insets.getTop()); - } - break; - } - } - } - - /** - * Gets the port constraints for this layer element. - * - * @return the port constraints - */ - public PortConstraints getPortConstraints() { - return portConstraints; - } - - /** - * Gets the rank width of this layer element. - * - * @return the rank width - */ - public int getRankWidth() { - return rankWidth; - } - - /** - * Gets the list of incoming layer connections. - * - * @return the incoming connections - */ - public List getIncomingConnections() { - return incoming; - } - - /** - * Gets the list of outgoing connections. - * - * @return the outgoing connections - */ - public List getOutgoingConnections() { - return outgoing; - } - - /** - * Gets the loops of this layer element. - * - * @return list of element loops - */ - public List getLoops() { - return loops; - } - - /** - * Returns the width of this layer element. - * - * @return the width - */ - public float getRealWidth() { - return realWidth; - } - - /** - * Returns the height of this layer element. - * - * @return the height - */ - public float getRealHeight() { - return realHeight; - } - - /** - * Sets the crosswise position for this layer element, considering all edges - * that are routed before this element. - * - * @param pos new crosswise position - * @param minDist minimal distance for routed edges - */ - public void setCrosswisePos(final float pos, final float minDist) { - Direction layoutDirection = layer.getLayeredGraph().getLayoutDirection(); - if (layoutDirection == Direction.DOWN) { - position.setX(pos + westRanks * minDist + preSpacingCross); - } else { - position.setY(pos + northRanks * minDist + preSpacingCross); - } - } - - /** - * Sets the lengthwise position for this layer element, considering all edges - * that are routed before this element. - * - * @param pos new lengthwise position - * @param minDist minimal distance for routed edges - */ - public void setLengthwisePos(final float pos, final float minDist) { - Direction layoutDirection = layer.getLayeredGraph().getLayoutDirection(); - if (layoutDirection == Direction.DOWN) { - position.setY(pos + northRanks * minDist + preSpacingLength); - } else { - position.setX(pos + westRanks * minDist + preSpacingLength); - } - } - - /** - * Gets the total crosswise dimension of this layer element with routed edges. - * - * @param minDist minimal distance for routed edges - * @param preSpacing whether the pre-spacing should be considered - * @return total crosswise dimension with routed edges - */ - public float getTotalCrosswiseDim(final float minDist, final boolean preSpacing) { - if (totalCrosswiseDim < 0.0f) { - Direction layoutDirection = layer.getLayeredGraph().getLayoutDirection(); - if (layoutDirection == Direction.DOWN) { - totalCrosswiseDim = (westRanks + eastRanks) * minDist + realWidth; - if (elemObj instanceof KNode) { - float minX = 0, maxX = realWidth; - KNode node = (KNode) elemObj; - for (KLabel label : node.getLabels()) { - KShapeLayout labelLayout = label.getData(KShapeLayout.class); - if (labelLayout.getXpos() < minX) { - minX = labelLayout.getXpos(); - } - if (labelLayout.getXpos() + labelLayout.getWidth() > maxX) { - maxX = labelLayout.getXpos() + labelLayout.getWidth(); - } - } - preSpacingCross = -minX; - totalCrosswiseDim += preSpacingCross + maxX - realWidth; - } - } else { - totalCrosswiseDim = (northRanks + southRanks) * minDist + realHeight; - if (elemObj instanceof KNode) { - float minY = 0, maxY = realHeight; - KNode node = (KNode) elemObj; - for (KLabel label : node.getLabels()) { - KShapeLayout labelLayout = label.getData(KShapeLayout.class); - if (labelLayout.getYpos() < minY) { - minY = labelLayout.getYpos(); - } - if (labelLayout.getYpos() + labelLayout.getHeight() > maxY) { - maxY = labelLayout.getYpos() + labelLayout.getHeight(); - } - } - preSpacingCross = -minY; - totalCrosswiseDim += preSpacingCross + maxY - realHeight; - } - } - } - if (preSpacing) { - return totalCrosswiseDim; - } else { - return totalCrosswiseDim - preSpacingCross; - } - } - - /** - * Gets the total lengthwise dimension of this layer element with routed edges. - * - * @param minDist minimal distance for routed edges - * @return total lengthwise dimension with routed edges - */ - public float getTotalLengthwiseDim(final float minDist) { - if (totalLengthwiseDim < 0.0f) { - Direction layoutDirection = layer.getLayeredGraph().getLayoutDirection(); - if (layoutDirection == Direction.DOWN) { - totalLengthwiseDim = (northRanks + southRanks) * minDist + realHeight; - if (elemObj instanceof KNode) { - float minY = 0, maxY = realHeight; - KNode node = (KNode) elemObj; - for (KPort port : node.getPorts()) { - KShapeLayout portLayout = port.getData(KShapeLayout.class); - if (portLayout.getYpos() < minY) { - minY = portLayout.getYpos(); - } else if (portLayout.getYpos() + portLayout.getHeight() > maxY) { - maxY = portLayout.getYpos() + portLayout.getHeight(); - } - for (KLabel label : port.getLabels()) { - KShapeLayout labelLayout = label.getData(KShapeLayout.class); - float ypos = portLayout.getYpos() + labelLayout.getYpos(); - if (ypos < minY) { - minY = ypos; - } else if (ypos + labelLayout.getHeight() > maxY) { - maxY = ypos + labelLayout.getHeight(); - } - } - } - for (KLabel label : node.getLabels()) { - KShapeLayout labelLayout = label.getData(KShapeLayout.class); - if (labelLayout.getYpos() < minY) { - minY = labelLayout.getYpos(); - } - if (labelLayout.getYpos() + labelLayout.getHeight() > maxY) { - maxY = labelLayout.getYpos() + labelLayout.getHeight(); - } - } - preSpacingLength = -minY; - totalLengthwiseDim += preSpacingLength + maxY - realHeight; - } - } else { - totalLengthwiseDim = (westRanks + eastRanks) * minDist + realWidth; - if (elemObj instanceof KNode) { - float minX = 0, maxX = realWidth; - KNode node = (KNode) elemObj; - for (KPort port : node.getPorts()) { - KShapeLayout portLayout = port.getData(KShapeLayout.class); - if (portLayout.getXpos() < minX) { - minX = portLayout.getXpos(); - } else if (portLayout.getXpos() + portLayout.getWidth() > maxX) { - maxX = portLayout.getXpos() + portLayout.getWidth(); - } - for (KLabel label : port.getLabels()) { - KShapeLayout labelLayout = label.getData(KShapeLayout.class); - float xpos = portLayout.getXpos() + labelLayout.getXpos(); - if (xpos < minX) { - minX = xpos; - } else if (xpos + labelLayout.getWidth() > maxX) { - maxX = xpos + labelLayout.getWidth(); - } - } - } - for (KLabel label : node.getLabels()) { - KShapeLayout labelLayout = label.getData(KShapeLayout.class); - if (labelLayout.getXpos() < minX) { - minX = labelLayout.getXpos(); - } - if (labelLayout.getXpos() + labelLayout.getWidth() > maxX) { - maxX = labelLayout.getXpos() + labelLayout.getWidth(); - } - } - preSpacingLength = -minX; - totalLengthwiseDim += preSpacingLength + maxX - realWidth; - } - } - } - return totalLengthwiseDim; - } - - /** - * Gets the current position of this layer element. - * - * @return the currently set position - */ - public KPoint getPosition() { - return position; - } - - /** - * Gets the current position offset of the contained node, or {@code null} - * if the contained object is not a node. - * - * @return the position offset - */ - public KPoint getPosOffset() { - return posOffset; - } - - /** - * Gets the object contained in this layer element. - * - * @return the element object - */ - public KGraphElement getElemObj() { - return elemObj; - } - - /** - * Gets the KIELER node associated with this layer element. - * - * @return the KIELER node - */ - public KSlimNode getKNode() { - return kNode; - } - - /** - * Clears the internal map of port ranks. - */ - public void clearPortRanks() { - portRanks = null; - } - - /** - * Gets the number of edges that are routed in front of this element. - * - * @return number of edges in front - */ - public int getEdgesFront() { - Direction layoutDirection = layer.getLayeredGraph().getLayoutDirection(); - return layoutDirection == Direction.DOWN ? northRanks : westRanks; - } - - /** - * Gets the number of edges that are routed in the back of this element. - * - * @return number of edges in the back - */ - public int getEdgesBack() { - Direction layoutDirection = layer.getLayeredGraph().getLayoutDirection(); - return layoutDirection == Direction.DOWN ? southRanks : eastRanks; - } - - /** - * Gets the port rank for a given port. - * - * @param port port for which the rank shall be obtained - * @param forward if true, ranks are determined for a forward layer sweep, - * else for a backwards layer sweep - * @return port rank, or 0 if {@code port == null} - */ - public int getPortRank(final KPort port, final boolean forward) { - if (port != null) { - if (portRanks == null) { - calcPortRanks(forward); - } - return portRanks.get(port).intValue(); - } else { - return 0; - } - } - - /** - * Determines the rank of each port of a layout node. - * - * @param forward if true, ranks are determined for a forward layer sweep, - * else for a backwards layer sweep - */ - private void calcPortRanks(final boolean forward) { - Direction layoutDirection = layer.getLayeredGraph().getLayoutDirection(); - portRanks = new HashMap(); - - if (elemObj instanceof KNode) { - // sort all ports by their relative position - KPort[] portArray = ((KNode) elemObj).getPorts().toArray(new KPort[0]); - Arrays.sort(portArray, new KimlUtil.PortComparator(forward, layoutDirection)); - // set the ranks in the newly sorted list - for (int i = 0; i < portArray.length; i++) { - portRanks.put(portArray[i], Integer.valueOf(i)); - } - } else if (elemObj instanceof KPort) { - portRanks.put((KPort) elemObj, Integer.valueOf(0)); - } - } - - /** - * Gets a list of combined element and port ranks for all incoming or for - * all outgoing connections. - * - * @param forward if true, only incoming connections are considered, else - * only outgoing connections are considered - * @return list of ranks for the specified connections - */ - public List getConnectionRanks(final boolean forward) { - List connectionRanks = new LinkedList(); - if (forward) { - if (elemObj instanceof KEdge && linearSegment.hasPreceding(this)) { - // only the preceding element of the linear segment may be - // considered - for (LayerConnection connection : incoming) { - LayerElement source = connection.getSourceElement(); - if (source.elemObj instanceof KEdge) { - connectionRanks.add(Integer.valueOf(source.rank)); - break; - } - } - } else { - for (LayerConnection connection : incoming) { - if (connection.getSourcePort() != null) { - // the source is a node with ports or a port - connectionRanks.add(Integer.valueOf(connection.getSourceElement().getPortRank( - connection.getSourcePort(), true) - + connection.getSourceElement().rank)); - } else { - // the source is a node without ports or an edge - connectionRanks.add(Integer.valueOf(connection.getSourceElement().rank)); - } - } - } - } else { - if (elemObj instanceof KEdge && linearSegment.hasFollowing(this)) { - // only the following element of the linear segment may be - // considered - for (LayerConnection connection : outgoing) { - LayerElement target = connection.getTargetElement(); - if (target.elemObj instanceof KEdge) { - connectionRanks.add(Integer.valueOf(target.rank)); - break; - } - } - } else { - for (LayerConnection connection : outgoing) { - if (connection.getTargetPort() != null) { - // the target is a node with ports or a port - connectionRanks.add(Integer.valueOf(connection.getTargetElement().getPortRank( - connection.getTargetPort(), false) - + connection.getTargetElement().rank)); - } else { - // the target is a node without ports or an edge - connectionRanks.add(Integer.valueOf(connection.getTargetElement().rank)); - } - } - } - } - return connectionRanks; - } - - /** - * Gets a list of combined element and port ranks of connections sorted by - * the port to which the connection is attached. This only works if the - * element object is a layout node. The method is expected to give at least - * an empty list for each port in the contained node group. - * - * @param forward if true, only incoming connections are considered, else - * only outgoing connections are considered - * @return list of connection ranks for each port of this layout node, or - * null if the contained object is not a layout node - */ - public Map> getConnectionRanksByPort(final boolean forward) { - if (elemObj instanceof KNode) { - KNode node = (KNode) elemObj; - Map> connectionRankMap = new LinkedHashMap>(); - for (KPort port : node.getPorts()) { - connectionRankMap.put(port, new LinkedList()); - } - - if (forward) { - for (LayerConnection connection : incoming) { - KPort targetPort = connection.getTargetPort(); - if (targetPort != null) { - List portList = connectionRankMap.get(targetPort); - if (connection.getSourcePort() != null) { - // the source is a node or a port - portList.add(Integer.valueOf(connection.getSourceElement().getPortRank( - connection.getSourcePort(), forward) - + connection.getSourceElement().rank)); - } else { - // the source is an edge - portList.add(Integer.valueOf(connection.getSourceElement().rank)); - } - } - } - } else { - for (LayerConnection connection : outgoing) { - KPort sourcePort = connection.getSourcePort(); - if (sourcePort != null) { - List portList = connectionRankMap.get(sourcePort); - if (connection.getTargetPort() != null) { - // the target is a node or a port - portList.add(Integer.valueOf(connection.getTargetElement().getPortRank( - connection.getTargetPort(), forward) - + connection.getTargetElement().rank)); - } else { - // the target is an edge - portList.add(Integer.valueOf(connection.getTargetElement().rank)); - } - } - } - } - - return connectionRankMap; - } else { - return null; - } - } - - /** - * Comparator used to sort ports using a list of abstract ranks. - */ - private static class DirectedPortComparator implements Comparator, Serializable { - /** the serial version UID. */ - private static final long serialVersionUID = 8667388280121765908L; - /** abstract ranks for some ports. */ - private Map abstractPortRanks; - private boolean forward, definedFirst; - - /** - * Creates a port comparator for a single list of abstract ranks. - * - * @param theabstractPortRanks abstract ranks for some ports - * @param theforward indicates whether to use the ranks in forward - * direction - * @param thedefinedFirst indicates whether to put ports with defined - * abstract rank before ports with undefined abstract rank - */ - DirectedPortComparator(final Map theabstractPortRanks, - final boolean theforward, final boolean thedefinedFirst) { - this.abstractPortRanks = theabstractPortRanks; - this.forward = theforward; - this.definedFirst = thedefinedFirst; - } - - /** - * {@inheritDoc} - */ - public int compare(final KPort port1, final KPort port2) { - Double arank1 = abstractPortRanks.get(port1); - Double arank2 = abstractPortRanks.get(port2); - if (arank1 == null && arank2 == null) { - int rank1 = port1.getData(KShapeLayout.class).getProperty(LayoutOptions.PORT_RANK); - int rank2 = port2.getData(KShapeLayout.class).getProperty(LayoutOptions.PORT_RANK); - return rank1 - rank2; - } else if (arank1 == null) { - return definedFirst ? 1 : -1; - } else if (arank2 == null) { - return definedFirst ? -1 : 1; - } else { - return forward ? arank1.compareTo(arank2) : arank2.compareTo(arank1); - } - } - } - - /** - * Sorts the ports on each side of the related node according to the given - * abstract ranks. - * - * @param abstractPortRanks abstract port ranks - * @param isoutgoing if true, the abstract ranks are assumed to be for - * outgoing connections, else for incoming connections - */ - public void sortPorts(final Map abstractPortRanks, final boolean isoutgoing) { - boolean vertical = layer.getLayeredGraph().getLayoutDirection() == Direction.DOWN; - Arrays.sort(northPorts, new DirectedPortComparator(abstractPortRanks, vertical ? !isoutgoing - : isoutgoing, !isoutgoing)); - Arrays.sort(eastPorts, new DirectedPortComparator(abstractPortRanks, vertical ? !isoutgoing - : isoutgoing, vertical ? !isoutgoing : isoutgoing)); - Arrays.sort(southPorts, new DirectedPortComparator(abstractPortRanks, vertical ? !isoutgoing - : isoutgoing, vertical ? !isoutgoing : isoutgoing)); - Arrays.sort(westPorts, new DirectedPortComparator(abstractPortRanks, vertical ? !isoutgoing - : isoutgoing, isoutgoing)); - assignPortRanks(); - } - - /** - * Comparator used to sort ports using two lists of abstract ranks. - */ - private static class SymmetricPortComparator implements Comparator, Serializable { - /** the serial version UID. */ - private static final long serialVersionUID = -2258577968632647502L; - private Map abstractPortRanks1, abstractPortRanks2; - private boolean list1First, firstForward; - - SymmetricPortComparator(final Map theabstractPortRanks1, - final Map theabstractPortRanks2, final boolean thelist1First, - final boolean thefirstForward) { - this.abstractPortRanks1 = theabstractPortRanks1; - this.abstractPortRanks2 = theabstractPortRanks2; - this.list1First = thelist1First; - this.firstForward = thefirstForward; - } - - /** - * {@inheritDoc} - */ - public int compare(final KPort port1, final KPort port2) { - Double a1rank1 = abstractPortRanks1.get(port1); - Double a2rank1 = abstractPortRanks2.get(port1); - Double a1rank2 = abstractPortRanks1.get(port2); - Double a2rank2 = abstractPortRanks2.get(port2); - if (a1rank1 != null && a1rank2 != null) { - return list1First && firstForward || !list1First && !firstForward ? a1rank1 - .compareTo(a1rank2) : a1rank2.compareTo(a1rank1); - } else if (a1rank1 != null && a2rank2 != null) { - return list1First ? -1 : 1; - } else if (a2rank1 != null && a1rank2 != null) { - return list1First ? 1 : -1; - } else if (a2rank1 != null && a2rank2 != null) { - return list1First && !firstForward || !list1First && firstForward ? a2rank1 - .compareTo(a2rank2) : a2rank2.compareTo(a2rank1); - } else if (a1rank1 != null || a2rank1 != null) { - return 1; - } else if (a1rank2 != null || a2rank2 != null) { - return -1; - } else { - return 0; - } - } - } - - /** - * Sorts the ports on each side of the related node according to the given - * abstract ranks. - * - * @param outgoingPortRanks ranks for ports with outgoing connections - * @param incomingPortRanks ranks for ports with incoming connections - */ - public void sortPorts(final Map outgoingPortRanks, - final Map incomingPortRanks) { - boolean vertical = layer.getLayeredGraph().getLayoutDirection() == Direction.DOWN; - Arrays.sort(northPorts, new SymmetricPortComparator(outgoingPortRanks, incomingPortRanks, false, - vertical)); - Arrays.sort(eastPorts, new SymmetricPortComparator(outgoingPortRanks, incomingPortRanks, - !vertical, true)); - Arrays.sort(southPorts, new SymmetricPortComparator(outgoingPortRanks, incomingPortRanks, - !vertical, true)); - Arrays.sort(westPorts, new SymmetricPortComparator(outgoingPortRanks, incomingPortRanks, true, - !vertical)); - assignPortRanks(); - } - - /** - * Assigns ranks to the ports of the related node according to the order of - * ports in the port lists. - */ - private void assignPortRanks() { - int portrank = 0; - for (KPort port : northPorts) { - port.getData(KShapeLayout.class).setProperty(LayoutOptions.PORT_RANK, - portrank++); - } - for (KPort port : eastPorts) { - port.getData(KShapeLayout.class).setProperty(LayoutOptions.PORT_RANK, - portrank++); - } - for (KPort port : southPorts) { - port.getData(KShapeLayout.class).setProperty(LayoutOptions.PORT_RANK, - portrank++); - } - for (KPort port : westPorts) { - port.getData(KShapeLayout.class).setProperty(LayoutOptions.PORT_RANK, - portrank++); - } - } - - /** - * Determines placements for the ports of the related node, based on the - * internally stored order. This order should be compatible to the assigned - * rank of each port. - */ - public void placePorts() { - if (elemObj instanceof KNode) { - KNode node = (KNode) elemObj; - float width = realWidth; - float height = realHeight; - if (portConstraints != PortConstraints.FIXED_POS) { - placePorts(northPorts, 0.0f, 0.0f, false, true, true, width); - placePorts(eastPorts, width, 0.0f, true, true, false, height); - placePorts(southPorts, width, height, false, false, false, width); - placePorts(westPorts, 0.0f, height, true, false, true, height); - } - - // determine new bounds for the contained node - float minX = 0.0f, minY = 0.0f, maxX = width, maxY = height; - for (KPort port : node.getPorts()) { - KShapeLayout portLayout = port.getData(KShapeLayout.class); - minX = Math.min(minX, portLayout.getXpos()); - minY = Math.min(minY, portLayout.getYpos()); - maxX = Math.max(maxX, portLayout.getXpos() + portLayout.getWidth()); - maxY = Math.max(maxY, portLayout.getYpos() + portLayout.getHeight()); - } - posOffset.setX(-minX); - posOffset.setY(-minY); - realWidth = maxX; - realHeight = maxY; - } - } - - /** - * Determines placements for the given ports, equally distributing them on a - * horizontal or vertical line. - * - * @param ports ports to place - * @param startX horizontal offset for placement - * @param startY vertical offset for placement - * @param vertical indicates whether ports shall be placed vertically - * @param forward indicates whether ports shall be placed in positive - * direction from the starting point - * @param subPortDim indicates whether port dimension shall be subtracted - * from each position - * @param length length of the line on which ports shall be placed - */ - private static void placePorts(final KPort[] ports, final float startX, final float startY, - final boolean vertical, final boolean forward, final boolean subPortDim, - final float length) { - float pos = vertical ? startY : startX; - float incr = length / (ports.length + 1); - if (!forward) { - incr = -incr; - } - for (KPort port : ports) { - pos += incr; - KShapeLayout portLayout = port.getData(KShapeLayout.class); - float offset = portLayout.getProperty(LayoutOptions.OFFSET); - float xpos, ypos; - if (vertical) { - xpos = startX; - if (subPortDim) { - xpos -= portLayout.getWidth() + offset; - } else { - xpos += offset; - } - ypos = pos - portLayout.getHeight() / 2; - } else { - xpos = pos - portLayout.getWidth() / 2; - ypos = startY; - if (subPortDim) { - ypos -= portLayout.getHeight() + offset; - } else { - ypos += offset; - } - } - portLayout.setXpos(xpos); - portLayout.setYpos(ypos); - } - } - - /** - * Sets the rank. - * - * @param therank the rank to set - */ - public void setRank(final int therank) { - this.rank = therank; - } - - /** - * Returns the rank. - * - * @return the rank - */ - public int getRank() { - return rank; - } - - /** - * Sets the linear segment. - * - * @param thelinearSegment the linear segment to set - */ - public void setLinearSegment(final LinearSegment thelinearSegment) { - this.linearSegment = thelinearSegment; - } - - /** - * Returns the linear segment. - * - * @return the linear segment - */ - public LinearSegment getLinearSegment() { - return linearSegment; - } - - /** - * Sets the ranks for a specific side. - * - * @param ranks the ranks to set - * @param side the side for which the ranks are set - */ - public void setRanks(final int ranks, final PortSide side) { - switch (side) { - case NORTH: - this.northRanks = ranks; - break; - case EAST: - this.eastRanks = ranks; - break; - case SOUTH: - this.southRanks = ranks; - break; - case WEST: - this.westRanks = ranks; - break; - } - } - - /** - * Returns the ranks for a specific side. - * - * @param side the side for which ranks are returned - * @return the ranks for the given side - */ - public int getRanks(final PortSide side) { - switch (side) { - case NORTH: - return northRanks; - case EAST: - return eastRanks; - case SOUTH: - return southRanks; - case WEST: - return westRanks; - } - return 0; - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/LayeredGraph.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/LayeredGraph.java (revision c6d39664cfb271f5286db0327ecaca0c47e77c8b) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/LayeredGraph.java (revision 0) @@ -1,517 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2008 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.structures; - -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; - -import de.cau.cs.kieler.core.kgraph.KEdge; -import de.cau.cs.kieler.core.kgraph.KGraphData; -import de.cau.cs.kieler.core.kgraph.KGraphElement; -import de.cau.cs.kieler.core.kgraph.KLabel; -import de.cau.cs.kieler.core.kgraph.KNode; -import de.cau.cs.kieler.core.kgraph.KPort; -import de.cau.cs.kieler.kiml.klayoutdata.KEdgeLayout; -import de.cau.cs.kieler.kiml.klayoutdata.KInsets; -import de.cau.cs.kieler.kiml.klayoutdata.KLayoutDataFactory; -import de.cau.cs.kieler.kiml.klayoutdata.KPoint; -import de.cau.cs.kieler.kiml.klayoutdata.KShapeLayout; -import de.cau.cs.kieler.kiml.options.Direction; -import de.cau.cs.kieler.kiml.options.LayoutOptions; -import de.cau.cs.kieler.kiml.options.PortConstraints; -import de.cau.cs.kieler.kiml.util.KimlUtil; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimEdge; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimGraph; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimNode; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.alg.ICycleRemover; - -/** - * This structure manages the layering of an acyclic directed graph. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class LayeredGraph { - - /** crosswise dimension of this layered graph. */ - private float crosswiseDim = 0.0f; - /** lengthwise dimension of this layered graph. */ - private float lengthwiseDim = 0.0f; - /** list of layers in this layered graph. */ - private List layers = new LinkedList(); - /** parent layout node associated with this layered graph. */ - private KNode parentNode; - /** map of objects to their corresponding layer. */ - private Map obj2LayerElemMap = new HashMap(); - /** map of ports to connected long edges. */ - private Map longEdgesMap = new HashMap(); - /** list of linear segments in this layered graph. */ - private List linearSegments = new LinkedList(); - /** layout direction for this layered graph: RIGHT or DOWN. */ - private Direction layoutDirection; - /** port constraints for the external ports. */ - private PortConstraints externalPortConstraints; - /** position of this layered graph. */ - private KPoint position; - - /** - * Creates a new layered graph. - * - * @param theparentNode parent layout node - */ - public LayeredGraph(final KNode theparentNode) { - position = KLayoutDataFactory.eINSTANCE.createKPoint(); - position.setX(0.0f); - position.setY(0.0f); - - // get layout options from the parent group - this.parentNode = theparentNode; - KGraphData layoutData = theparentNode.getData(KShapeLayout.class); - layoutDirection = layoutData.getProperty(LayoutOptions.DIRECTION); - if (layoutDirection == Direction.UNDEFINED) { - layoutDirection = Direction.RIGHT; - } - externalPortConstraints = layoutData.getProperty(LayoutOptions.PORT_CONSTRAINTS); - } - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - String text = getClass().getSimpleName(); - if (parentNode.getLabels().size() > 0) { - text += "(" + parentNode.getLabels().get(0).getText() + ")"; - } - return text; - } - - /** - * Put the given object into a layer with specified rank. The search for the - * right layer begins at the front of the internal list. - * - * @param obj object to put - * @param rank rank of the object - * @param kNode the corresponding node in the acyclic KIELER graph - */ - public void putFront(final KGraphElement obj, final int rank, final KSlimNode kNode) { - ListIterator layerIter = layers.listIterator(); - while (layerIter.hasNext()) { - Layer layer = layerIter.next(); - if (layer.getRank() < 0 || layer.getRank() > rank) { - // insert a new layer into the list - Layer newLayer = new Layer(rank, Layer.UNDEF_HEIGHT, this); - doPut(obj, newLayer, kNode); - layerIter.previous(); - layerIter.add(newLayer); - return; - } else if (layer.getRank() == rank) { - // the right layer was found - doPut(obj, layer, kNode); - return; - } - } - - // add a new layer at the end of the list - Layer newLayer = new Layer(rank, Layer.UNDEF_HEIGHT, this); - doPut(obj, newLayer, kNode); - layers.add(newLayer); - } - - /** - * Put the given object into a layer with specified height. The search for - * the right layer begins at the back of the internal list. - * - * @param obj object to put - * @param height height of the object - * @param kNode the corresponding node in the acyclic KIELER graph - */ - public void putBack(final KGraphElement obj, final int height, final KSlimNode kNode) { - ListIterator layerIter = layers.listIterator(layers.size()); - while (layerIter.hasPrevious()) { - Layer layer = layerIter.previous(); - if (layer.getHeight() < 0 || layer.getHeight() > height) { - // insert a new layer into the list - Layer newLayer = new Layer(Layer.UNDEF_RANK, height, this); - doPut(obj, newLayer, kNode); - layerIter.next(); - layerIter.add(newLayer); - return; - } else if (layer.getHeight() == height) { - // the right layer was found - doPut(obj, layer, kNode); - return; - } - } - - // add a new layer at the start of the list - Layer newLayer = new Layer(Layer.UNDEF_RANK, height, this); - doPut(obj, newLayer, kNode); - layers.add(0, newLayer); - } - - /** - * Gets the layer element that holds the given object. - * - * @param obj the object - * @return the corresponding layer element, or null if none exists - */ - public LayerElement getLayerElement(final Object obj) { - return obj2LayerElemMap.get(obj); - } - - /** - * Gets the list of layers. - * - * @return the layers - */ - public List getLayers() { - return layers; - } - - /** - * Gets the parent layout node. - * - * @return the parent node - */ - public KNode getParentNode() { - return parentNode; - } - - /** - * Creates connections between layer elements and creates long edges. This - * method should be called after all nodes and ports have been put into the - * layered graph. - * - * @param kGraph acyclic version of the graph - */ - public void createConnections(final KSlimGraph kGraph) { - for (Layer layer : layers) { - List elements = layer.getElements(); - for (int i = 0; i < elements.size(); i++) { - // avoid ConcurrentModificationExceptions - LayerElement element = elements.get(i); - if (element.getLinearSegment() == null) { - // create new linear segment - createLinearSegment(element); - } - List outgoingEdges = element.getOutgoingEdges(); - if (outgoingEdges != null) { - for (KSlimEdge edge : outgoingEdges) { - KEdge layoutEdge = (KEdge) edge.getObject(); - KNode targetNode; - KPort sourcePort, targetPort; - if (edge.getRank() == ICycleRemover.REVERSED) { - targetNode = layoutEdge.getSource(); - sourcePort = layoutEdge.getTargetPort(); - targetPort = layoutEdge.getSourcePort(); - } else { - targetNode = layoutEdge.getTarget(); - sourcePort = layoutEdge.getSourcePort(); - targetPort = layoutEdge.getTargetPort(); - } - - if (edge.getTarget().getObject() instanceof KNode) { - createConnection(element, obj2LayerElemMap.get(targetNode), layoutEdge, - sourcePort, targetPort); - } else if (targetPort != null) { - createConnection(element, obj2LayerElemMap.get(targetPort), layoutEdge, - sourcePort, targetPort); - } - } - } - } - // assign ranks to all elements of the current layer - layer.calcElemRanks(); - } - } - - /** - * Applies the layout of this layered graph to the contained layout graph. - */ - public void applyLayout() { - KShapeLayout parentLayout = parentNode.getData(KShapeLayout.class); - KInsets insets = parentLayout.getInsets(); - // apply the new layout to the contained elements - for (Layer layer : layers) { - for (LayerElement element : layer.getElements()) { - element.applyLayout(position, insets); - for (LayerConnection connection : element.getIncomingConnections()) { - connection.applyLayout(position, insets); - } - for (ElementLoop loop : element.getLoops()) { - loop.applyLayout(position); - } - } - } - - // layout the edge labels - // TODO the label sizes are not considered yet, would need to change preceding phases - for (KNode child : parentNode.getChildren()) { - for (KEdge edge : child.getOutgoingEdges()) { - layoutEdgeLabels(edge); - } - } - for (KEdge edge : parentNode.getOutgoingEdges()) { - if (parentNode.equals(edge.getTarget().getParent())) { - layoutEdgeLabels(edge); - } - } - - // update the size of the parent layout node - float width = insets.getLeft() + insets.getRight(); - float height = insets.getTop() + insets.getBottom(); - if (layoutDirection == Direction.DOWN) { - width += crosswiseDim; - height += lengthwiseDim; - } else { - width += lengthwiseDim; - height += crosswiseDim; - } - KimlUtil.resizeNode(parentNode, width, height, false); - - // update layout options of the parent layout node - parentLayout.setProperty(LayoutOptions.PORT_CONSTRAINTS, PortConstraints.FIXED_POS); - KimlUtil.calcPortRanks(parentNode); - } - - /** - * Gets the layout direction: RIGHT or DOWN. - * - * @return the layout direction - */ - public Direction getLayoutDirection() { - return layoutDirection; - } - - /** - * Returns the port constraints for external ports. - * - * @return the port constraints for external ports - */ - public PortConstraints getExternalPortConstraints() { - return externalPortConstraints; - } - - /** - * Gets the list of linear segments of this layered graph. Each real node is - * assigned a unique linear segment of size 1. - * - * @return list of linear segments - */ - public List getLinearSegments() { - return linearSegments; - } - - /** - * Gets the current layout position of this layered graph. - * - * @return the position - */ - public KPoint getPosition() { - return position; - } - - /** - * Sets the crosswise dimension, that is the height for horizontal - * layout or the width for vertical layout. - * - * @param thecrosswiseDim the crosswise dimension to set - */ - public void setCrosswiseDim(final float thecrosswiseDim) { - this.crosswiseDim = thecrosswiseDim; - } - - /** - * Returns the crosswise dimension, that is the height for horizontal - * layout or the width for vertical layout. - * - * @return the crosswise dimension - */ - public float getCrosswiseDim() { - return crosswiseDim; - } - - /** - * Sets the lengthwise dimension, that is the width for horizontal - * layout or the height for vertical layout. - * - * @param thelengthwiseDim the lengthwise dimension to set - */ - public void setLengthwiseDim(final float thelengthwiseDim) { - this.lengthwiseDim = thelengthwiseDim; - } - - /** - * Returns the lengthwise dimension, that is the width for horizontal - * layout or the height for vertical layout. - * - * @return the lengthwise dimension - */ - public float getLengthwiseDim() { - return lengthwiseDim; - } - - /** - * Puts an object into a given layer. - * - * @param obj object to put - * @param layer the layer - * @param kNode the corresponding node in the acyclic KIELER graph - */ - private void doPut(final KGraphElement obj, final Layer layer, final KSlimNode kNode) { - LayerElement element = layer.put(obj, kNode); - obj2LayerElemMap.put(obj, element); - } - - /** - * Creates a cross-layer connection between two layer elements, possibly - * leading to a linear segment of edge elements. - * - * @param source source element - * @param target target element - * @param edge the edge object connecting both elements - * @param sourcePort the source port - * @param targetPort the target port - */ - private void createConnection(final LayerElement source, final LayerElement target, - final KEdge edge, final KPort sourcePort, final KPort targetPort) { - Layer sourceLayer = source.getLayer(); - Layer targetLayer = target.getLayer(); - if (targetLayer.getRank() - sourceLayer.getRank() == 1) { - source.addOutgoing(edge, target, sourcePort, targetPort); - } else { - LayerElement currentElement = null; - // process existing long edges for the source or target port - LinearSegment linearSegment = longEdgesMap.get(sourcePort); - if (linearSegment == null - || linearSegment.getElements().get(0).getLayer().getRank() < sourceLayer.getRank()) { - linearSegment = longEdgesMap.get(targetPort); - } - if (linearSegment != null) { - ListIterator elemIter = linearSegment.getElements().listIterator(); - currentElement = elemIter.next(); - while (elemIter.hasNext() && currentElement.getLayer().getRank() - <= sourceLayer.getRank()) { - currentElement = elemIter.next(); - } - source.addOutgoing(edge, currentElement, sourcePort, null); - while (elemIter.hasNext() && currentElement.getLayer().getRank() - < targetLayer.getRank() - 1) { - currentElement = elemIter.next(); - } - } else { - currentElement = sourceLayer.getNext().put(edge, null); - linearSegment = createLinearSegment(currentElement); - source.addOutgoing(edge, currentElement, sourcePort, null); - } - // add new layer elements to the linear segment if needed - while (currentElement.getLayer().getRank() < targetLayer.getRank() - 1) { - LayerElement newElement = currentElement.getLayer().getNext().put(edge, null); - linearSegment.getElements().add(newElement); - newElement.setLinearSegment(linearSegment); - currentElement.addOutgoing(edge, newElement); - currentElement = newElement; - } - currentElement.addOutgoing(edge, target, null, targetPort); - longEdgesMap.put(sourcePort, linearSegment); - longEdgesMap.put(targetPort, linearSegment); - } - } - - /** - * Creates a new linear segment that contains the given element. - * - * @param element layer element that is put into the new linear segment - */ - private LinearSegment createLinearSegment(final LayerElement element) { - LinearSegment linearSegment = new LinearSegment(); - linearSegment.getElements().add(element); - element.setLinearSegment(linearSegment); - linearSegments.add(linearSegment); - return linearSegment; - } - - /** spacing for edge labels. */ - private static final int LABEL_SPACING = 3; - - /** - * Performs a rudimentary layout of edge labels. Does not avoid overlappings of labels - * with other labels, nodes, or edges. - * - * @param edge the edge for which the labels shall be layouted - */ - private void layoutEdgeLabels(final KEdge edge) { - List tailLabels = new LinkedList(); - List centerLabels = new LinkedList(); - List headLabels = new LinkedList(); - KEdgeLayout edgeLayout = edge.getData(KEdgeLayout.class); - int midBendPoint = edgeLayout.getBendPoints().size() / 2; - for (KLabel edgeLabel : edge.getLabels()) { - switch (edgeLabel.getData(KShapeLayout.class) - .getProperty(LayoutOptions.EDGE_LABEL_PLACEMENT)) { - case CENTER: - if (midBendPoint > 0) { - centerLabels.add(edgeLabel); - } else { - tailLabels.add(edgeLabel); - } - break; - case TAIL: - tailLabels.add(edgeLabel); - break; - case HEAD: - headLabels.add(edgeLabel); - break; - } - } - - // layout tail labels - float xpos = edgeLayout.getSourcePoint().getX() + LABEL_SPACING; - float ypos = edgeLayout.getSourcePoint().getY() + LABEL_SPACING; - for (KLabel edgeLabel : tailLabels) { - KShapeLayout labelLayout = edgeLabel.getData(KShapeLayout.class); - labelLayout.setXpos(xpos); - labelLayout.setYpos(ypos); - ypos += labelLayout.getHeight() + LABEL_SPACING; - } - - // layout center labels - if (!centerLabels.isEmpty()) { - KPoint point = edgeLayout.getBendPoints().get(midBendPoint); - xpos = point.getX() + LABEL_SPACING; - ypos = point.getY() + LABEL_SPACING; - for (KLabel edgeLabel : centerLabels) { - KShapeLayout labelLayout = edgeLabel.getData(KShapeLayout.class); - labelLayout.setXpos(xpos); - labelLayout.setYpos(ypos); - ypos += labelLayout.getHeight() + LABEL_SPACING; - } - } - - // layout tail labels - xpos = edgeLayout.getTargetPoint().getX() - LABEL_SPACING; - ypos = edgeLayout.getTargetPoint().getY(); - for (KLabel edgeLabel : headLabels) { - KShapeLayout labelLayout = edgeLabel.getData(KShapeLayout.class); - ypos -= labelLayout.getHeight() - LABEL_SPACING; - labelLayout.setXpos(xpos - labelLayout.getWidth()); - labelLayout.setYpos(ypos); - } - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/LinearSegment.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/LinearSegment.java (revision e40423edcc5feed14a967696da575e26a251c7db) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/LinearSegment.java (revision 0) @@ -1,113 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2008 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.structures; - -import java.util.LinkedList; -import java.util.List; - -/** - * A linear segment of layer elements that represents a long edge in a layered - * graph. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class LinearSegment implements Comparable { - - /** list of layer elements contained in this linear segment. */ - private List elements = new LinkedList(); - /** current rank of the linear segment. */ - private int rank = -1; - - /** - * Determines whether the given element has preceding elements in this - * linear segment. - * - * @param elem element to test - * @return true if there are other elements before elem - */ - public boolean hasPreceding(final LayerElement elem) { - return elements.indexOf(elem) > 0; - } - - /** - * Determines whether the given element has following elements in this - * linear segment. - * - * @param elem element to test - * @return true if there are other elements after elem - */ - public boolean hasFollowing(final LayerElement elem) { - return elements.indexOf(elem) < elements.size() - 1; - } - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - return "seg:" + rank; - } - - /** - * {@inheritDoc} - */ - public int compareTo(final LinearSegment other) { - return this.rank == other.rank ? 0 : (this.rank > other.rank ? 1 : -1); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean equals(final Object obj) { - return obj instanceof LinearSegment && ((LinearSegment) obj).rank == this.rank; - } - - /** - * {@inheritDoc} - */ - @Override - public int hashCode() { - return rank; - } - - /** - * Returns the elements. - * - * @return the elements - */ - public List getElements() { - return elements; - } - - /** - * Sets the rank. - * - * @param therank the rank to set - */ - public void setRank(final int therank) { - this.rank = therank; - } - - /** - * Returns the rank. - * - * @return the rank - */ - public int getRank() { - return rank; - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/RoutingSlot.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/RoutingSlot.java (revision e40423edcc5feed14a967696da575e26a251c7db) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/RoutingSlot.java (revision 0) @@ -1,93 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2008 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.structures; - -/** - * A routing slot is a place in which layer connections can be routed. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class RoutingSlot { - - /** the slot rank determines the lengthwise distance to the preceding layer. */ - private int rank = 0; - /** crosswise starting position of this slot. */ - private float start; - /** crosswise ending position of this slot. */ - private float end; - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - return "slot:" + Math.round(start) + "-" + Math.round(end); - } - - /** - * Sets the rank. - * - * @param therank the rank to set - */ - public void setRank(final int therank) { - this.rank = therank; - } - - /** - * Returns the rank. - * - * @return the rank - */ - public int getRank() { - return rank; - } - - /** - * Sets the start. - * - * @param thestart the start to set - */ - public void setStart(final float thestart) { - this.start = thestart; - } - - /** - * Returns the start. - * - * @return the start - */ - public float getStart() { - return start; - } - - /** - * Sets the end. - * - * @param theend the end to set - */ - public void setEnd(final float theend) { - this.end = theend; - } - - /** - * Returns the end. - * - * @return the end - */ - public float getEnd() { - return end; - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/package-info.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/package-info.java (revision 707f02f4f5c7cb48536a13bb7408fa43d26a5bee) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/package-info.java (revision 0) @@ -1,20 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ - -/** - * The layered graph data structure used internally by the - * hierarchical dataflow layout algorithm. - */ -// TODO explain connection between classes? -package de.cau.cs.kieler.klodd.hierarchical.structures; Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/KSlimEdge.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/KSlimEdge.java (revision 8f1d84ae1efad2f1032a0e8a3f89852c58b82c7b) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/KSlimEdge.java (revision 0) @@ -1,378 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph; - -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; - -/** - * An edge in the slim graph structure. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class KSlimEdge extends KSlimGraphElement { - - /** - * Definition of an edge bend for orthogonal drawing. - */ - public static class Bend { - /** Type of edge bend, from the perspective of the source node. */ - public enum Type { - /** undefined. */ - UNDEFINED, - /** left bend. */ - LEFT, - /** right bend. */ - RIGHT - } - - /** the type of edge bend. */ - private final Type type; - /** the x coordinate position. */ - private float xpos; - /** the y coordinate position. */ - private float ypos; - /** the index of this bend. */ - private final int index; - /** the edge associated with this bend. */ - private final KSlimEdge edge; - - /** - * Creates an edge bend of given type. - * - * @param theedge the edge to which the new bend is added - * @param thetype type of edge bend - */ - public Bend(final KSlimEdge theedge, final Type thetype) { - this.edge = theedge; - this.type = thetype; - this.index = theedge.getBends().size(); - } - - /** - * Returns the bend type. - * - * @return the type - */ - public Type getType() { - return type; - } - - /** - * Sets the x position. - * - * @param thexpos the x position to set - */ - public void setXpos(final float thexpos) { - this.xpos = thexpos; - } - - /** - * Returns the x position. - * - * @return the x position - */ - public float getXpos() { - return xpos; - } - - /** - * @param theypos the ypos to set - */ - public void setYpos(final float theypos) { - this.ypos = theypos; - } - - /** - * Returns the y position. - * - * @return the y position - */ - public float getYpos() { - return ypos; - } - - /** - * Returns the index. - * - * @return the index - */ - public int getIndex() { - return index; - } - - /** - * Returns the slim edge associated with this bend. - * - * @return the edge - */ - public KSlimEdge getEdge() { - return edge; - } - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - return type.toString(); - } - } - - /** source node. */ - private KSlimNode source; - /** target node. */ - private KSlimNode target; - /** left face. */ - private KSlimFace leftFace; - /** right face. */ - private KSlimFace rightFace; - /** the bends of this edge. */ - private final List bends = new LinkedList(); - /** the side on which the edge leaves the source. */ - private KSlimNode.Side sourceSide = KSlimNode.Side.UNDEFINED; - /** the side on which the edge reaches the target. */ - private KSlimNode.Side targetSide = KSlimNode.Side.UNDEFINED; - - /** - * Creates an edge connecting two existing nodes. - * - * @param graph the graph to which the new edge shall be added - * @param thesource source node - * @param thetarget target node - */ - public KSlimEdge(final KSlimGraph graph, final KSlimNode thesource, - final KSlimNode thetarget) { - graph.getEdges().add(this); - this.setId(graph.nextEdgeId()); - this.source = thesource; - this.target = thetarget; - } - - /** - * Creates an edge connecting two existing nodes, with an object to be - * contained. - * - * @param graph the graph to which the new edge shall be added - * @param thesource source node - * @param thetarget target node - * @param theobj object to be contained - */ - public KSlimEdge(final KSlimGraph graph, final KSlimNode thesource, - final KSlimNode thetarget, final Object theobj) { - this(graph, thesource, thetarget); - this.setObject(theobj); - } - - /** - * Connects this edge with the source and target. New incidence entries are - * created for the incidence lists of the source and the target. - */ - public void connectNodes() { - source.getIncidence().add(new KSlimNode.IncEntry(this, KSlimNode.IncEntry.Type.OUT)); - target.getIncidence().add(new KSlimNode.IncEntry(this, KSlimNode.IncEntry.Type.IN)); - } - - /** - * Connects this edge with the source and target with given ranks. New - * incidence entries are created for the incidence lists of the source and - * the target. - * - * @param sourceRank rank of the edge at source - * @param targetRank rank of the edge at target - * @param forwardSelfLoop for self-loops: is the target rank greater than - * the source rank? - */ - public void connectNodes(final int sourceRank, final int targetRank, - final boolean forwardSelfLoop) { - int thetargetRank = targetRank; - if (source.getId() == target.getId() - && (sourceRank < targetRank || (sourceRank == targetRank - && forwardSelfLoop))) { - thetargetRank++; - } - source.getIncidence().add(sourceRank, new KSlimNode.IncEntry(this, - KSlimNode.IncEntry.Type.OUT)); - target.getIncidence().add(thetargetRank, new KSlimNode.IncEntry(this, - KSlimNode.IncEntry.Type.IN)); - } - - /** - * Connects this edge with the source and target respecting the order of - * incidence according to the given node sides. - * - * @param thesourceSide port side at the source node - * @param thetargetSide port side at the target node - */ - public void connectNodes(final KSlimNode.Side thesourceSide, - final KSlimNode.Side thetargetSide) { - this.sourceSide = thesourceSide; - this.targetSide = thetargetSide; - ListIterator incIter = source.getIncidence().listIterator(); - while (incIter.hasNext()) { - KSlimNode.IncEntry nextEntry = incIter.next(); - KSlimNode.Side side = (nextEntry.getType() == KSlimNode.IncEntry.Type.OUT - ? nextEntry.getEdge().sourceSide : nextEntry.getEdge().targetSide); - if (thesourceSide.compareTo(side) <= 0) { - incIter.previous(); - break; - } - } - incIter.add(new KSlimNode.IncEntry(this, KSlimNode.IncEntry.Type.OUT)); - incIter = target.getIncidence().listIterator(); - while (incIter.hasNext()) { - KSlimNode.IncEntry nextEntry = incIter.next(); - KSlimNode.Side side = (nextEntry.getType() == KSlimNode.IncEntry.Type.OUT - ? nextEntry.getEdge().sourceSide : nextEntry.getEdge().targetSide); - if (thetargetSide.compareTo(side) <= 0) { - incIter.previous(); - break; - } - } - incIter.add(new KSlimNode.IncEntry(this, KSlimNode.IncEntry.Type.IN)); - } - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - String baseString = super.toString(); - if (source != null && target != null) { - return baseString + " " + source.getId() + ">" + target.getId(); - } else { - return baseString; - } - } - - /** - * Sets the source. - * - * @param thesource the source to set - */ - public void setSource(final KSlimNode thesource) { - this.source = thesource; - } - - /** - * Returns the source. - * - * @return the source - */ - public KSlimNode getSource() { - return source; - } - - /** - * Sets the target. - * - * @param thetarget the target to set - */ - public void setTarget(final KSlimNode thetarget) { - this.target = thetarget; - } - - /** - * Returns the target. - * - * @return the target - */ - public KSlimNode getTarget() { - return target; - } - - /** - * Sets the leftFace. - * - * @param theleftFace the leftFace to set - */ - public void setLeftFace(final KSlimFace theleftFace) { - this.leftFace = theleftFace; - } - - /** - * Returns the left face. - * - * @return the left face - */ - public KSlimFace getLeftFace() { - return leftFace; - } - - /** - * Sets the right face. - * - * @param therightFace the right face to set - */ - public void setRightFace(final KSlimFace therightFace) { - this.rightFace = therightFace; - } - - /** - * Returns the rightFace. - * - * @return the rightFace - */ - public KSlimFace getRightFace() { - return rightFace; - } - - /** - * Returns the bends. - * - * @return the bends - */ - public List getBends() { - return bends; - } - - /** - * Sets the source side. - * - * @param thesourceSide the source side to set - */ - public void setSourceSide(final KSlimNode.Side thesourceSide) { - this.sourceSide = thesourceSide; - } - - /** - * Returns the source side. - * - * @return the source side - */ - public KSlimNode.Side getSourceSide() { - return sourceSide; - } - - /** - * Sets the target side. - * - * @param thetargetSide the target side to set - */ - public void setTargetSide(final KSlimNode.Side thetargetSide) { - this.targetSide = thetargetSide; - } - - /** - * Returns the target side. - * - * @return the target side - */ - public KSlimNode.Side getTargetSide() { - return targetSide; - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/KSlimFace.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/KSlimFace.java (revision 8f1d84ae1efad2f1032a0e8a3f89852c58b82c7b) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/KSlimFace.java (revision 0) @@ -1,211 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph; - -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; - -/** - * A face in the slim graph structure. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class KSlimFace extends KSlimGraphElement { - - /** - * An entry of a list associated with a face. - */ - public static class BorderEntry { - /** an edge bordering this face. */ - private final KSlimEdge edge; - /** indicates whether the bordering edge is traversed forward. */ - private final boolean forward; - - /** - * Creates a border entry for the given edge. - * - * @param theedge edge bordering the containing face - * @param theforward indicates whether the bordering edge is traversed forward - */ - public BorderEntry(final KSlimEdge theedge, final boolean theforward) { - this.edge = theedge; - this.forward = theforward; - } - - /** - * Creates a border entry copying an existing one. - * - * @param entry border entry to copy - */ - public BorderEntry(final BorderEntry entry) { - this.edge = entry.edge; - this.forward = entry.forward; - } - - /** - * Returns the opposed face, as seen from the containing face. - * - * @return the left face if the contained edge is forward, else the - * right face - */ - public KSlimFace opposed() { - if (forward) { - return edge.getLeftFace(); - } else { - return edge.getRightFace(); - } - } - - /** - * Returns the first node encountered when traversing the edge in - * forward direction. - * - * @return the source if the contained edge is forward, else the target - */ - public KSlimNode firstNode() { - if (forward) { - return edge.getSource(); - } else { - return edge.getTarget(); - } - } - - /** - * Returns the second node encountered when traversing the edge in - * forward direction. - * - * @return the target if the contained edge is forward, else the source - */ - public KSlimNode secondNode() { - if (forward) { - return edge.getTarget(); - } else { - return edge.getSource(); - } - } - - /** - * Returns the side of the contained edge at the first encountered node. - * - * @return the side at source if the contained edge is forward, else the - * side at target - */ - public KSlimNode.Side firstSide() { - if (forward) { - return edge.getSourceSide(); - } else { - return edge.getTargetSide(); - } - } - - /** - * Returns the side of the contained edge at the second encountered - * node. - * - * @return the side at target if the contained edge is forward, else the - * side at source - */ - public KSlimNode.Side secondSide() { - if (forward) { - return edge.getTargetSide(); - } else { - return edge.getSourceSide(); - } - } - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - if (forward) { - return ">" + edge.getId(); - } else { - return "<" + edge.getId(); - } - } - - /** - * Returns the edge. - * - * @return the edge - */ - public KSlimEdge getEdge() { - return edge; - } - - /** - * Returns whether the bordering edge is traversed forward. - * - * @return the forward - */ - public boolean isForward() { - return forward; - } - } - - /** - * set of lists of bordering edges (can be multiple lists for the external face). - */ - private final List> borders = new LinkedList>(); - - /** - * Creates a face and optionally adds it to the given graph. - * - * @param graph graph to which the new face shall be added - * @param addToInternal if true, the new face is added to the graph's list - * of internal faces - */ - public KSlimFace(final KSlimGraph graph, final boolean addToInternal) { - if (addToInternal) { - graph.getFaces().add(this); - } - this.setId(graph.nextFaceId()); - } - - /** - * Gets a list iterator with the current position at the given edge. The - * returned iterator has its cursor directly after the edge. - * - * @param edge edge at which the iterator shall point - * @param forward is the given edge forward for this face? - * @return iterator pointing at edge, or null if the edge was - * not found - */ - public ListIterator getIterator(final KSlimEdge edge, - final boolean forward) { - for (List border : borders) { - ListIterator borderIter = border.listIterator(); - while (borderIter.hasNext()) { - BorderEntry nextEntry = borderIter.next(); - if (nextEntry.edge.getId() == edge.getId() && nextEntry.forward == forward) { - return borderIter; - } - } - } - return null; - } - - /** - * Returns the borders. - * - * @return the borders - */ - public List> getBorders() { - return borders; - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/KSlimGraph.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/KSlimGraph.java (revision 8f1d84ae1efad2f1032a0e8a3f89852c58b82c7b) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/KSlimGraph.java (revision 0) @@ -1,169 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph; - -import java.util.LinkedList; -import java.util.List; - -/** - * The general-purpose slim graph structure. This structure is specially - * designed for use in graph algorithms for undirected graphs, because each node - * has only one incidence list for both the incoming and the outgoing edges. - * However, the direction of each edge can be obtained by a respective entry in - * the incidence list of the respective node. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class KSlimGraph { - - /** list of nodes in this TSM graph. */ - private final List nodes = new LinkedList(); - /** list of edges in this TSM graph. */ - private final List edges = new LinkedList(); - /** list of internal faces in this TSM graph. */ - private final List faces = new LinkedList(); - /** the external face of this TSM graph. */ - private KSlimFace externalFace = new KSlimFace(this, false); - - /** total width of the graph. */ - private float width; - /** total height of the graph. */ - private float height; - - /** next available identifier for nodes. */ - private int nextNodeId = 0; - /** next available identifier for edges. */ - private int nextEdgeId = 0; - /** next available identifier for faces. */ - private int nextFaceId = 0; - - /** - * Returns the next node identifier and increases it by one. - * - * @return the next node id - */ - int nextNodeId() { - return nextNodeId++; - } - - /** - * Returns the next edge identifier and increases it by one. - * - * @return the next edge id - */ - int nextEdgeId() { - return nextEdgeId++; - } - - /** - * Returns the next face identifier and increases it by one. - * - * @return the next face id - */ - int nextFaceId() { - return nextFaceId++; - } - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - return "SlimGraph(" + getNodes().size() + " nodes, " + getEdges().size() - + " edges, " + (getFaces().size() + 1) + " faces)"; - } - - /** - * Returns the nodes. - * - * @return the nodes - */ - public List getNodes() { - return nodes; - } - - /** - * Returns the edges. - * - * @return the edges - */ - public List getEdges() { - return edges; - } - - /** - * Returns the faces. - * - * @return the faces - */ - public List getFaces() { - return faces; - } - - /** - * Sets the externalFace. - * - * @param theexternalFace the externalFace to set - */ - public void setExternalFace(final KSlimFace theexternalFace) { - this.externalFace = theexternalFace; - } - - /** - * Returns the externalFace. - * - * @return the externalFace - */ - public KSlimFace getExternalFace() { - return externalFace; - } - - /** - * Sets the width. - * - * @param thewidth the width to set - */ - public void setWidth(final float thewidth) { - this.width = thewidth; - } - - /** - * Returns the width. - * - * @return the width - */ - public float getWidth() { - return width; - } - - /** - * Sets the height. - * - * @param theheight the height to set - */ - public void setHeight(final float theheight) { - this.height = theheight; - } - - /** - * Returns the height. - * - * @return the height - */ - public float getHeight() { - return height; - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/KSlimGraphElement.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/KSlimGraphElement.java (revision 8f1d84ae1efad2f1032a0e8a3f89852c58b82c7b) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/KSlimGraphElement.java (revision 0) @@ -1,117 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph; - -/** - * An element of a slim graph, which can be a node, an edge or a face. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public abstract class KSlimGraphElement implements Comparable { - - /** identifier of this element, determined at creation time. */ - private int id; - /** rank of this element, used by various algorithms. */ - private int rank = 0; - /** object contained in this element, or null if there is none. */ - private Object object = null; - - /** - * {@inheritDoc} - */ - public int compareTo(final KSlimGraphElement other) { - return this.id - other.id; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean equals(final Object other) { - return (other instanceof KSlimGraphElement && other.getClass() == this.getClass()) - && ((KSlimGraphElement) other).id == this.id; - } - - /** - * {@inheritDoc} - */ - @Override - public int hashCode() { - return getClass().hashCode() + id; - } - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - return getClass().getSimpleName() + "(" + id + ")"; - } - - /** - * Sets the id. - * - * @param theid the id to set - */ - protected void setId(final int theid) { - this.id = theid; - } - - /** - * Returns the id. - * - * @return the id - */ - public int getId() { - return id; - } - - /** - * Sets the rank. - * - * @param therank the rank to set - */ - public void setRank(final int therank) { - this.rank = therank; - } - - /** - * Returns the rank. - * - * @return the rank - */ - public int getRank() { - return rank; - } - - /** - * Sets the object. - * - * @param theobject the object to set - */ - protected void setObject(final Object theobject) { - this.object = theobject; - } - - /** - * Returns the object. - * - * @return the object - */ - public Object getObject() { - return object; - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/KSlimNode.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/KSlimNode.java (revision 8f1d84ae1efad2f1032a0e8a3f89852c58b82c7b) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/KSlimNode.java (revision 0) @@ -1,313 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph; - -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; - -/** - * A node in the slim graph structure. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class KSlimNode extends KSlimGraphElement { - - /** - * Single entry of a incidence list. - */ - public static class IncEntry { - /** type of incidence entry: incoming or outgoing edge. */ - public enum Type { - /** incoming edge. */ - IN, - /** outgoing edge. */ - OUT - } - - /** the edge of this incidence entry. */ - private final KSlimEdge edge; - /** type of incidence: incoming or outgoing. */ - private Type type; - - /** - * Creates an incidence list entry. - * - * @param theedge the edge - * @param thetype the incidence type - */ - public IncEntry(final KSlimEdge theedge, final Type thetype) { - this.edge = theedge; - this.setType(thetype); - } - - /** - * Returns the endpoint of this incidence entry, as seen from the - * containing node. - * - * @return the source of the edge if this is an incoming type, else the - * target of the edge - */ - public KSlimNode endpoint() { - if (type == Type.IN) { - return edge.getSource(); - } else { - return edge.getTarget(); - } - } - - /** - * Returns the left face of this incidence entry, as seen from the - * containing node. - * - * @return the right face of the edge if this is an incoming type, else - * the left face of the edge - */ - public KSlimFace leftFace() { - if (type == Type.IN) { - return edge.getRightFace(); - } else { - return edge.getLeftFace(); - } - } - - /** - * Returns the side of the containing node on which this incidence entry - * lies. - * - * @return the target side of the edge if this is an incoming type, else - * the source side - */ - public Side side() { - if (type == Type.IN) { - return edge.getTargetSide(); - } else { - return edge.getSourceSide(); - } - } - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - return type.toString() + edge.getId(); - } - - /** - * Returns the edge. - * - * @return the edge - */ - public KSlimEdge getEdge() { - return edge; - } - - /** - * Sets the type. - * - * @param thetype the type to set - */ - public void setType(final Type thetype) { - this.type = thetype; - } - - /** - * Returns the type. - * - * @return the type - */ - public Type getType() { - return type; - } - } - - /** - * Definition of sides of a node. The order of side definitions ensures that - * the default enumeration comparator implementation respects the node sides - * found in clockwise order. - */ - public static enum Side { - /** the side is undefined. */ - UNDEFINED, - /** north side. */ - NORTH, - /** east side. */ - EAST, - /** south side. */ - SOUTH, - /** west side. */ - WEST; - - /** - * Returns the next side in clockwise order. - * - * @return the next side in clockwise order - */ - public Side right() { - switch (this) { - case NORTH: - return EAST; - case EAST: - return SOUTH; - case SOUTH: - return WEST; - case WEST: - return NORTH; - default: - return UNDEFINED; - } - } - - /** - * Returns the next side in counter-clockwise order. - * - * @return the next side in counter-clockwise order - */ - public Side left() { - switch (this) { - case NORTH: - return WEST; - case EAST: - return NORTH; - case SOUTH: - return EAST; - case WEST: - return SOUTH; - default: - return UNDEFINED; - } - } - - /** - * Returns the opposed side. - * - * @return the opposed side - */ - public Side opposed() { - switch (this) { - case NORTH: - return SOUTH; - case EAST: - return WEST; - case SOUTH: - return NORTH; - case WEST: - return EAST; - default: - return UNDEFINED; - } - } - } - - /** list of incident edges. */ - private final List incidence = new LinkedList(); - /** concrete x coordinate position. */ - private float xpos; - /** concrete y coordinate position. */ - private float ypos; - - /** - * Creates a node containing the given object. - * - * @param graph the graph to which the new node shall be added - * @param obj the object to be contained - */ - public KSlimNode(final KSlimGraph graph, final Object obj) { - graph.getNodes().add(this); - this.setObject(obj); - this.setId(graph.nextNodeId()); - } - - /** - * Creates a node containing no object. - * - * @param graph the graph to which the new node shall be added - */ - public KSlimNode(final KSlimGraph graph) { - graph.getNodes().add(this); - this.setObject(null); - this.setId(graph.nextNodeId()); - } - - /** - * Gets a list iterator for this node's incidence list, with the current - * position at the given edge. The returned list iterator has its cursor - * directly after the edge - * - * @param edge edge at which the iterator shall point - * @param outgoing is the given edge an outgoing edge? - * @return iterator pointing at edge, or null if the edge was - * not found - */ - public ListIterator getIterator(final KSlimEdge edge, - final boolean outgoing) { - ListIterator edgeIter = incidence.listIterator(); - while (edgeIter.hasNext()) { - IncEntry nextEntry = edgeIter.next(); - if (nextEntry.edge.getId() == edge.getId() - && (nextEntry.type == IncEntry.Type.OUT) == outgoing) { - return edgeIter; - } - } - return null; - } - - /** - * Returns the incidence. - * - * @return the incidence - */ - public List getIncidence() { - return incidence; - } - - /** - * Sets the xpos. - * - * @param thexpos the xpos to set - */ - public void setXpos(final float thexpos) { - this.xpos = thexpos; - } - - /** - * Returns the xpos. - * - * @return the xpos - */ - public float getXpos() { - return xpos; - } - - /** - * Sets the ypos. - * - * @param theypos the ypos to set - */ - public void setYpos(final float theypos) { - this.ypos = theypos; - } - - /** - * Returns the ypos. - * - * @return the ypos - */ - public float getYpos() { - return ypos; - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/alg/AbstractCycleRemover.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/alg/AbstractCycleRemover.java (revision 8f1d84ae1efad2f1032a0e8a3f89852c58b82c7b) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/alg/AbstractCycleRemover.java (revision 0) @@ -1,103 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.alg; - -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; - -import de.cau.cs.kieler.core.alg.AbstractAlgorithm; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimEdge; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimNode; - -/** - * Abstract superclass that can be used for implementations of cycle remover - * algorithms which operate by reversing edges. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public abstract class AbstractCycleRemover extends AbstractAlgorithm implements ICycleRemover { - - /** list of edges that are reversed and later restored. */ - private LinkedList reversedEdges = null; - - /** - * {@inheritDoc} - */ - @Override - public void reset() { - super.reset(); - reversedEdges = null; - } - - /** - * {@inheritDoc} - */ - public void restoreGraph() { - if (reversedEdges != null) { - reverseEdges(); - } - } - - /** - * {@inheritDoc} - */ - public List getReversedEdges() { - if (reversedEdges == null) { - throw new IllegalStateException("removeCycles must be called before getReversedEdges."); - } else { - return reversedEdges; - } - } - - /** - * Sets the reversed edges. - * - * @param thereversedEdges the reversed edges - */ - protected void setReversedEdges(final LinkedList thereversedEdges) { - this.reversedEdges = thereversedEdges; - } - - /** - * Switches the source and target of all edges marked in the - * reversedEdges list. - */ - protected void reverseEdges() { - for (KSlimEdge edge : reversedEdges) { - edge.setRank(ICycleRemover.REVERSED); - // change incidence type at source and target - ListIterator sourceIter = edge.getSource().getIterator(edge, true); - ListIterator targetIter = edge.getTarget().getIterator(edge, false); - if (sourceIter != null) { - sourceIter.previous().setType(KSlimNode.IncEntry.Type.IN); - } - if (targetIter != null) { - targetIter.previous().setType(KSlimNode.IncEntry.Type.OUT); - } - - // reverse source and target node - KSlimNode source = edge.getSource(); - KSlimNode.Side sourceSide = edge.getSourceSide(); - KSlimNode target = edge.getTarget(); - KSlimNode.Side targetSide = edge.getTargetSide(); - edge.setSource(target); - edge.setSourceSide(targetSide); - edge.setTarget(source); - edge.setTargetSide(sourceSide); - } - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/alg/DFSCycleRemover.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/alg/DFSCycleRemover.java (revision 8f1d84ae1efad2f1032a0e8a3f89852c58b82c7b) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/alg/DFSCycleRemover.java (revision 0) @@ -1,91 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.alg; - -import java.util.Iterator; -import java.util.LinkedList; - -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimEdge; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimGraph; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimNode; - -/** - * Cycle remover that uses a depth first search to remove cycles. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class DFSCycleRemover extends AbstractCycleRemover { - - /** next DFS number to use. */ - private int nextDfs; - - /** - * {@inheritDoc} - */ - public void removeCycles(final KSlimGraph graph) { - getMonitor().begin("DFS cycle removal", 1); - setReversedEdges(new LinkedList()); - nextDfs = 1; - - // initialize node ranks - for (KSlimNode node : graph.getNodes()) { - node.setRank(-1); - } - - // mark back edges of the DFS run - Iterator nodeIter = graph.getNodes().iterator(); - while (nodeIter.hasNext()) { - KSlimNode node = nodeIter.next(); - if (node.getRank() < 0) { - // node was not visited yet - dfsVisit(node); - } - } - // reverse all marked edges - reverseEdges(); - - getMonitor().done(); - } - - /** - * Visits a node in the DFS algorithm. This method is recursive. - * - * @param node node to visit - */ - private void dfsVisit(final KSlimNode node) { - // put DFS mark on the new node - node.setRank(nextDfs++); - - // process all outgoing edges - for (KSlimNode.IncEntry edgeEntry : node.getIncidence()) { - if (edgeEntry.getType() == KSlimNode.IncEntry.Type.OUT) { - KSlimNode targetNode = edgeEntry.getEdge().getTarget(); - if (targetNode.getRank() >= 0) { - if (targetNode.getRank() > 0 && targetNode.getId() != node.getId()) { - // a cycle was found, break it - getReversedEdges().add(edgeEntry.getEdge()); - } - } else { - // target node was not visited yet - dfsVisit(targetNode); - edgeEntry.getEdge().setRank(0); - } - } - } - // backtracking: set this node's number to 0 - node.setRank(0); - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/alg/GreedyCycleRemover.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/alg/GreedyCycleRemover.java (revision 8f1d84ae1efad2f1032a0e8a3f89852c58b82c7b) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/alg/GreedyCycleRemover.java (revision 0) @@ -1,158 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.alg; - -import java.util.LinkedList; - -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimEdge; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimGraph; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimNode; - -/** - * Cycle remover implementation that uses a greedy algorithm. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class GreedyCycleRemover extends AbstractCycleRemover { - - /** indegree values for the nodes. */ - private int[] indeg; - /** outdegree values for the nodes. */ - private int[] outdeg; - /** list of source nodes. */ - private final LinkedList sources = new LinkedList(); - /** list of sink nodes. */ - private final LinkedList sinks = new LinkedList(); - - /** - * {@inheritDoc} - */ - @Override - public void reset() { - super.reset(); - sources.clear(); - sinks.clear(); - } - - /** - * {@inheritDoc} - */ - public void removeCycles(final KSlimGraph graph) { - getMonitor().begin("Greedy cycle removal", 1); - setReversedEdges(new LinkedList()); - - // initialize values for the algorithm - int unprocessedNodes = graph.getNodes().size(); - indeg = new int[unprocessedNodes]; - outdeg = new int[unprocessedNodes]; - int nextRight = -1, nextLeft = 1; - for (KSlimNode node : graph.getNodes()) { - node.setRank(0); - for (KSlimNode.IncEntry edgeEntry : node.getIncidence()) { - if (edgeEntry.getType() == KSlimNode.IncEntry.Type.OUT) { - outdeg[node.getId()]++; - } else { - indeg[node.getId()]++; - } - } - if (outdeg[node.getId()] == 0) { - sinks.add(node); - } else if (indeg[node.getId()] == 0) { - sources.add(node); - } - } - - // assign ranks to all nodes - while (unprocessedNodes > 0) { - while (!sinks.isEmpty()) { - KSlimNode sink = sinks.removeFirst(); - sink.setRank(nextRight--); - updateNeighbors(sink); - unprocessedNodes--; - } - while (!sources.isEmpty()) { - KSlimNode source = sources.removeFirst(); - source.setRank(nextLeft++); - updateNeighbors(source); - unprocessedNodes--; - } - if (unprocessedNodes != 0) { - int maxOutflow = Integer.MIN_VALUE; - KSlimNode maxNode = null; - for (KSlimNode node : graph.getNodes()) { - if (node.getRank() == 0) { - int outflow = outdeg[node.getId()] - indeg[node.getId()]; - if (outflow > maxOutflow) { - maxOutflow = outflow; - maxNode = node; - } - } - } - maxNode.setRank(nextLeft++); - updateNeighbors(maxNode); - unprocessedNodes--; - } - } - - // shift negative ranks - int shiftBase = graph.getNodes().size() + 1; - for (KSlimNode node : graph.getNodes()) { - if (node.getRank() < 0) { - node.setRank(node.getRank() + shiftBase); - } - } - - // mark edges that point left - for (KSlimEdge edge : graph.getEdges()) { - if (edge.getSource().getRank() > edge.getTarget().getRank()) { - getReversedEdges().add(edge); - } else { - edge.setRank(0); - } - } - - // reverse all marked edges - reverseEdges(); - - getMonitor().done(); - } - - /** - * Updates indegree and outdegree values of the neighbors of the given node, - * simulating its removal from the graph. the sources and sinks lists are - * also updated. - * - * @param node node for which neighbors are updated - */ - private void updateNeighbors(final KSlimNode node) { - for (KSlimNode.IncEntry edgeEntry : node.getIncidence()) { - KSlimNode endpoint = edgeEntry.endpoint(); - if (endpoint.getRank() == 0) { - if (edgeEntry.getType() == KSlimNode.IncEntry.Type.OUT) { - indeg[endpoint.getId()]--; - if (indeg[endpoint.getId()] == 0 && outdeg[endpoint.getId()] != 0) { - sources.add(endpoint); - } - } else { - outdeg[endpoint.getId()]--; - if (outdeg[endpoint.getId()] == 0 && indeg[endpoint.getId()] != 0) { - sinks.add(endpoint); - } - } - } - } - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/alg/ICycleRemover.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/alg/ICycleRemover.java (revision 8f1d84ae1efad2f1032a0e8a3f89852c58b82c7b) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/alg/ICycleRemover.java (revision 0) @@ -1,55 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.alg; - -import java.util.List; - -import de.cau.cs.kieler.core.alg.IAlgorithm; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimEdge; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimGraph; - -/** - * Interface for algorithms for removal of cycles in a layout graph. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public interface ICycleRemover extends IAlgorithm { - - /** rank value for edges that were reversed. */ - int REVERSED = 1; - - /** - * Remove cycles in a given graph. Loops on a single node are ignored and - * have to be processed properly in later steps. Each edge is assigned a - * rank with value REVERSED if and only if the edge was - * reversed for cycle removal. - * - * @param graph graph to be processed - */ - void removeCycles(KSlimGraph graph); - - /** - * Restore the original graph after cycles have been removed. - */ - void restoreGraph(); - - /** - * Returns the list of edges that were reversed for cycle removal. - * - * @return list of reversed edges - */ - List getReversedEdges(); - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/alg/InteractiveCycleRemover.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/alg/InteractiveCycleRemover.java (revision 8f1d84ae1efad2f1032a0e8a3f89852c58b82c7b) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/alg/InteractiveCycleRemover.java (revision 0) @@ -1,74 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2010 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.alg; - -import java.util.LinkedList; - -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimEdge; -import de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.KSlimGraph; - -/** - * A cycle remover that allows interactive layout by considering the node - * positions given by the user. - * - * @author msp - */ -public class InteractiveCycleRemover extends AbstractCycleRemover { - - /** whether vertical layout is active. */ - private boolean vertical = false; - - /** - * {@inheritDoc} - */ - public void removeCycles(final KSlimGraph graph) { - getMonitor().begin("Interactive cycle removal", 1); - setReversedEdges(new LinkedList()); - - // mark edges that point left / up - if (vertical) { - for (KSlimEdge edge : graph.getEdges()) { - if (edge.getSource().getYpos() > edge.getTarget().getYpos()) { - getReversedEdges().add(edge); - } else { - edge.setRank(0); - } - } - } else { - for (KSlimEdge edge : graph.getEdges()) { - if (edge.getSource().getXpos() > edge.getTarget().getXpos()) { - getReversedEdges().add(edge); - } else { - edge.setRank(0); - } - } - } - - // reverse all marked edges - reverseEdges(); - - getMonitor().done(); - } - - /** - * Activate vertical layout. - * - * @param thevertical if true, vertical layout is done, else - * horizontal layout is done - */ - public void setVertical(final boolean thevertical) { - this.vertical = thevertical; - } - -} Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/alg/package-info.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/alg/package-info.java (revision 8f1d84ae1efad2f1032a0e8a3f89852c58b82c7b) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/alg/package-info.java (revision 0) @@ -1,19 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ - -/** - * Algorithms for the slim graph data structure. These are general - * graph algorithms that are used in various contexts. - */ -package de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph.alg; Index: plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/package-info.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/package-info.java (revision 8f1d84ae1efad2f1032a0e8a3f89852c58b82c7b) +++ plugins/de.cau.cs.kieler.klodd.hierarchical/src/de/cau/cs/kieler/klodd/hierarchical/structures/slimgraph/package-info.java (revision 0) @@ -1,25 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ - -/** - * Slim graph representation for undirected graphs, used in many - * graph algorithms. Although edges do have a direction, the incoming - * and outgoing edges of a node are stored in the same incidence list. - * This makes this graph structure very suitable for algorithms for - * undirected graphs such as planarity related algorithms. - *

- * The dual graph, which consists of faces and edges separating those - * faces, can be generated from a slim graph instance. - */ -package de.cau.cs.kieler.klodd.hierarchical.structures.slimgraph; Index: plugins/de.cau.cs.kieler.klodd.ui/.classpath =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.ui/.classpath (revision 793f0325b52206c2fa9caf5c639651f6605a9dc7) +++ plugins/de.cau.cs.kieler.klodd.ui/.classpath (revision 0) @@ -1,7 +0,0 @@ - - - - - - - Index: plugins/de.cau.cs.kieler.klodd.ui/.project =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.ui/.project (revision cf51ddd2cf94979c15aa8cbcf4e1f0951db33e50) +++ plugins/de.cau.cs.kieler.klodd.ui/.project (revision 0) @@ -1,34 +0,0 @@ - - - de.cau.cs.kieler.klodd.ui - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - net.sf.eclipsecs.core.CheckstyleBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - net.sf.eclipsecs.core.CheckstyleNature - - Index: plugins/de.cau.cs.kieler.klodd.ui/.settings/org.eclipse.jdt.core.prefs =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.ui/.settings/org.eclipse.jdt.core.prefs (revision 5aa9dede5708c0f79d6f1ea6061c52bfdc911912) +++ plugins/de.cau.cs.kieler.klodd.ui/.settings/org.eclipse.jdt.core.prefs (revision 0) @@ -1,12 +0,0 @@ -#Fri Jan 09 13:44:53 CET 2009 -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.5 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.5 Index: plugins/de.cau.cs.kieler.klodd.ui/META-INF/MANIFEST.MF =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.ui/META-INF/MANIFEST.MF (revision dc2f0f61bfbb0ea308bfce5d265425de5a405028) +++ plugins/de.cau.cs.kieler.klodd.ui/META-INF/MANIFEST.MF (revision 0) @@ -1,15 +0,0 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: KIELER Hierarchical Dataflow Layout UI -Bundle-SymbolicName: de.cau.cs.kieler.klodd.ui;singleton:=true -Bundle-Version: 0.3.1.qualifier -Require-Bundle: org.eclipse.core.runtime;bundle-version="3.4.0", - org.eclipse.ui;bundle-version="3.4.0", - de.cau.cs.kieler.core, - de.cau.cs.kieler.core.ui, - de.cau.cs.kieler.kiml, - de.cau.cs.kieler.klodd.hierarchical -Bundle-ActivationPolicy: lazy -Bundle-Activator: de.cau.cs.kieler.klodd.ui.KloddUIPlugin -Bundle-Vendor: Christian-Albrechts-Universität zu Kiel -Bundle-RequiredExecutionEnvironment: J2SE-1.5 Index: plugins/de.cau.cs.kieler.klodd.ui/README.txt =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.ui/README.txt (revision 2f10ad81a7e7fca32407898dbc66cb8332681da1) +++ plugins/de.cau.cs.kieler.klodd.ui/README.txt (revision 0) @@ -1,5 +0,0 @@ -| de.cau.cs.kieler.klodd.ui -\______________________________________ - -User interface for the KLoDD layouters, contains a preference page and -extensions for the KIML layout interface. Index: plugins/de.cau.cs.kieler.klodd.ui/build.properties =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.ui/build.properties (revision 40837037d8ef982a7e846214aac60961bf091080) +++ plugins/de.cau.cs.kieler.klodd.ui/build.properties (revision 0) @@ -1,9 +0,0 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - plugin.xml,\ - epl-v10.html,\ - images/ -src.includes = epl-v10.html,\ - README.txt Index: plugins/de.cau.cs.kieler.klodd.ui/epl-v10.html =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.ui/epl-v10.html (revision 5aa9dede5708c0f79d6f1ea6061c52bfdc911912) +++ plugins/de.cau.cs.kieler.klodd.ui/epl-v10.html (revision 0) @@ -1,262 +0,0 @@ - - - - - - -Eclipse Public License - Version 1.0 - - - - - - -

Eclipse Public License - v 1.0

- -

THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE -PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR -DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS -AGREEMENT.

- -

1. DEFINITIONS

- -

"Contribution" means:

- -

a) in the case of the initial Contributor, the initial -code and documentation distributed under this Agreement, and

-

b) in the case of each subsequent Contributor:

- -

i) changes to the Program, and

-

ii) additions to the Program;

-

where such changes and/or additions to the Program -originate from and are distributed by that particular Contributor. A -Contribution 'originates' from a Contributor if it was added to the -Program by such Contributor itself or anyone acting on such -Contributor's behalf. Contributions do not include additions to the -Program which: (i) are separate modules of software distributed in -conjunction with the Program under their own license agreement, and (ii) -are not derivative works of the Program.

- -

"Contributor" means any person or entity that distributes -the Program.

- -

"Licensed Patents" mean patent claims licensable by a -Contributor which are necessarily infringed by the use or sale of its -Contribution alone or when combined with the Program.

- -

"Program" means the Contributions distributed in accordance -with this Agreement.

- -

"Recipient" means anyone who receives the Program under -this Agreement, including all Contributors.

- -

2. GRANT OF RIGHTS

- -

a) Subject to the terms of this Agreement, each -Contributor hereby grants Recipient a non-exclusive, worldwide, -royalty-free copyright license to reproduce, prepare derivative works -of, publicly display, publicly perform, distribute and sublicense the -Contribution of such Contributor, if any, and such derivative works, in -source code and object code form.

- -

b) Subject to the terms of this Agreement, each -Contributor hereby grants Recipient a non-exclusive, worldwide, -royalty-free patent license under Licensed Patents to make, use, sell, -offer to sell, import and otherwise transfer the Contribution of such -Contributor, if any, in source code and object code form. This patent -license shall apply to the combination of the Contribution and the -Program if, at the time the Contribution is added by the Contributor, -such addition of the Contribution causes such combination to be covered -by the Licensed Patents. The patent license shall not apply to any other -combinations which include the Contribution. No hardware per se is -licensed hereunder.

- -

c) Recipient understands that although each Contributor -grants the licenses to its Contributions set forth herein, no assurances -are provided by any Contributor that the Program does not infringe the -patent or other intellectual property rights of any other entity. Each -Contributor disclaims any liability to Recipient for claims brought by -any other entity based on infringement of intellectual property rights -or otherwise. As a condition to exercising the rights and licenses -granted hereunder, each Recipient hereby assumes sole responsibility to -secure any other intellectual property rights needed, if any. For -example, if a third party patent license is required to allow Recipient -to distribute the Program, it is Recipient's responsibility to acquire -that license before distributing the Program.

- -

d) Each Contributor represents that to its knowledge it -has sufficient copyright rights in its Contribution, if any, to grant -the copyright license set forth in this Agreement.

- -

3. REQUIREMENTS

- -

A Contributor may choose to distribute the Program in object code -form under its own license agreement, provided that:

- -

a) it complies with the terms and conditions of this -Agreement; and

- -

b) its license agreement:

- -

i) effectively disclaims on behalf of all Contributors -all warranties and conditions, express and implied, including warranties -or conditions of title and non-infringement, and implied warranties or -conditions of merchantability and fitness for a particular purpose;

- -

ii) effectively excludes on behalf of all Contributors -all liability for damages, including direct, indirect, special, -incidental and consequential damages, such as lost profits;

- -

iii) states that any provisions which differ from this -Agreement are offered by that Contributor alone and not by any other -party; and

- -

iv) states that source code for the Program is available -from such Contributor, and informs licensees how to obtain it in a -reasonable manner on or through a medium customarily used for software -exchange.

- -

When the Program is made available in source code form:

- -

a) it must be made available under this Agreement; and

- -

b) a copy of this Agreement must be included with each -copy of the Program.

- -

Contributors may not remove or alter any copyright notices contained -within the Program.

- -

Each Contributor must identify itself as the originator of its -Contribution, if any, in a manner that reasonably allows subsequent -Recipients to identify the originator of the Contribution.

- -

4. COMMERCIAL DISTRIBUTION

- -

Commercial distributors of software may accept certain -responsibilities with respect to end users, business partners and the -like. While this license is intended to facilitate the commercial use of -the Program, the Contributor who includes the Program in a commercial -product offering should do so in a manner which does not create -potential liability for other Contributors. Therefore, if a Contributor -includes the Program in a commercial product offering, such Contributor -("Commercial Contributor") hereby agrees to defend and -indemnify every other Contributor ("Indemnified Contributor") -against any losses, damages and costs (collectively "Losses") -arising from claims, lawsuits and other legal actions brought by a third -party against the Indemnified Contributor to the extent caused by the -acts or omissions of such Commercial Contributor in connection with its -distribution of the Program in a commercial product offering. The -obligations in this section do not apply to any claims or Losses -relating to any actual or alleged intellectual property infringement. In -order to qualify, an Indemnified Contributor must: a) promptly notify -the Commercial Contributor in writing of such claim, and b) allow the -Commercial Contributor to control, and cooperate with the Commercial -Contributor in, the defense and any related settlement negotiations. The -Indemnified Contributor may participate in any such claim at its own -expense.

- -

For example, a Contributor might include the Program in a commercial -product offering, Product X. That Contributor is then a Commercial -Contributor. If that Commercial Contributor then makes performance -claims, or offers warranties related to Product X, those performance -claims and warranties are such Commercial Contributor's responsibility -alone. Under this section, the Commercial Contributor would have to -defend claims against the other Contributors related to those -performance claims and warranties, and if a court requires any other -Contributor to pay any damages as a result, the Commercial Contributor -must pay those damages.

- -

5. NO WARRANTY

- -

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS -PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS -OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, -ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY -OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely -responsible for determining the appropriateness of using and -distributing the Program and assumes all risks associated with its -exercise of rights under this Agreement , including but not limited to -the risks and costs of program errors, compliance with applicable laws, -damage to or loss of data, programs or equipment, and unavailability or -interruption of operations.

- -

6. DISCLAIMER OF LIABILITY

- -

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT -NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING -WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR -DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED -HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

- -

7. GENERAL

- -

If any provision of this Agreement is invalid or unenforceable under -applicable law, it shall not affect the validity or enforceability of -the remainder of the terms of this Agreement, and without further action -by the parties hereto, such provision shall be reformed to the minimum -extent necessary to make such provision valid and enforceable.

- -

If Recipient institutes patent litigation against any entity -(including a cross-claim or counterclaim in a lawsuit) alleging that the -Program itself (excluding combinations of the Program with other -software or hardware) infringes such Recipient's patent(s), then such -Recipient's rights granted under Section 2(b) shall terminate as of the -date such litigation is filed.

- -

All Recipient's rights under this Agreement shall terminate if it -fails to comply with any of the material terms or conditions of this -Agreement and does not cure such failure in a reasonable period of time -after becoming aware of such noncompliance. If all Recipient's rights -under this Agreement terminate, Recipient agrees to cease use and -distribution of the Program as soon as reasonably practicable. However, -Recipient's obligations under this Agreement and any licenses granted by -Recipient relating to the Program shall continue and survive.

- -

Everyone is permitted to copy and distribute copies of this -Agreement, but in order to avoid inconsistency the Agreement is -copyrighted and may only be modified in the following manner. The -Agreement Steward reserves the right to publish new versions (including -revisions) of this Agreement from time to time. No one other than the -Agreement Steward has the right to modify this Agreement. The Eclipse -Foundation is the initial Agreement Steward. The Eclipse Foundation may -assign the responsibility to serve as the Agreement Steward to a -suitable separate entity. Each new version of the Agreement will be -given a distinguishing version number. The Program (including -Contributions) may always be distributed subject to the version of the -Agreement under which it was received. In addition, after a new version -of the Agreement is published, Contributor may elect to distribute the -Program (including its Contributions) under the new version. Except as -expressly stated in Sections 2(a) and 2(b) above, Recipient receives no -rights or licenses to the intellectual property of any Contributor under -this Agreement, whether expressly, by implication, estoppel or -otherwise. All rights in the Program not expressly granted under this -Agreement are reserved.

- -

This Agreement is governed by the laws of the State of New York and -the intellectual property laws of the United States of America. No party -to this Agreement will bring a legal action under this Agreement more -than one year after the cause of action arose. Each party waives its -rights to a jury trial in any resulting litigation.

- - - - Index: plugins/de.cau.cs.kieler.klodd.ui/images/hierarchical.png =================================================================== diff -u -N -r40837037d8ef982a7e846214aac60961bf091080 -r5e866f77221b5d565bca27eb735349f3207da540 Binary files differ Index: plugins/de.cau.cs.kieler.klodd.ui/plugin.xml =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.ui/plugin.xml (revision caa3ca26cb6fca0f3f735cc068403582b354bc2c) +++ plugins/de.cau.cs.kieler.klodd.ui/plugin.xml (revision 0) @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Index: plugins/de.cau.cs.kieler.klodd.ui/src/de/cau/cs/kieler/klodd/ui/KloddUIPlugin.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.ui/src/de/cau/cs/kieler/klodd/ui/KloddUIPlugin.java (revision e9a0654c0c35ba318b3c3a7b819838f7f6403a3e) +++ plugins/de.cau.cs.kieler.klodd.ui/src/de/cau/cs/kieler/klodd/ui/KloddUIPlugin.java (revision 0) @@ -1,87 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.ui; - -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.ui.plugin.AbstractUIPlugin; -import org.osgi.framework.BundleContext; - -import de.cau.cs.kieler.core.IKielerPreferenceStore; -import de.cau.cs.kieler.core.ui.KielerPreferenceStore; -import de.cau.cs.kieler.klodd.hierarchical.HierarchicalDataflowLayoutProvider; - -/** - * The activator class controls the plug-in life cycle. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author Miro Spönemann - */ -public class KloddUIPlugin extends AbstractUIPlugin { - - /** the plug-in ID. */ - public static final String PLUGIN_ID = "de.cau.cs.kieler.klodd.core"; - /** name of the KLoDD layouters collection. */ - public static final String COLLECTION_NAME = "KLoDD Layouters"; - - /** the shared instance. */ - private static KloddUIPlugin plugin; - - /** - * The constructor. - */ - public KloddUIPlugin() { - } - - /** - * {@inheritDoc} - */ - @Override - public void start(final BundleContext context) throws Exception { - super.start(context); - plugin = this; - // set preference stores - IKielerPreferenceStore preferenceStore = new KielerPreferenceStore(getPreferenceStore()); - HierarchicalDataflowLayoutProvider.setPreferenceStore(preferenceStore); - // OrthogonalDataflowLayoutProvider.setPreferenceStore(preferenceStore); - } - - /** - * {@inheritDoc} - */ - @Override - public void stop(final BundleContext context) throws Exception { - plugin = null; - super.stop(context); - } - - /** - * Returns the shared instance. - * - * @return the shared instance - */ - public static KloddUIPlugin getDefault() { - return plugin; - } - - /** - * Returns an image descriptor for the image file at the given plug-in - * relative path. - * - * @param path the path - * @return the image descriptor - */ - public static ImageDescriptor getImageDescriptor(final String path) { - return imageDescriptorFromPlugin(PLUGIN_ID, path); - } -} Index: plugins/de.cau.cs.kieler.klodd.ui/src/de/cau/cs/kieler/klodd/ui/Messages.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.ui/src/de/cau/cs/kieler/klodd/ui/Messages.java (revision e40423edcc5feed14a967696da575e26a251c7db) +++ plugins/de.cau.cs.kieler.klodd.ui/src/de/cau/cs/kieler/klodd/ui/Messages.java (revision 0) @@ -1,52 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.ui; - -import java.util.MissingResourceException; -import java.util.ResourceBundle; - -/** - * Class for access to internationalized strings. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public final class Messages { - - /** - * Hidden constructor. - */ - private Messages() { - } - - private static final String BUNDLE_NAME = "de.cau.cs.kieler.klodd.ui.messages"; //$NON-NLS-1$ - private static ResourceBundle resourceBundle = null; - - /** - * Returns a string for the given key. - * - * @param key key to lookup - * @return readable message string - */ - public static String getString(final String key) { - try { - if (resourceBundle == null) { - resourceBundle = ResourceBundle.getBundle(BUNDLE_NAME); - } - return resourceBundle.getString(key); - } catch (MissingResourceException e) { - return '!' + key + '!'; - } - } -} Index: plugins/de.cau.cs.kieler.klodd.ui/src/de/cau/cs/kieler/klodd/ui/messages.properties =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.ui/src/de/cau/cs/kieler/klodd/ui/messages.properties (revision aa1d8532df7469f92c8750ddfe9ba5a976f8cd4e) +++ plugins/de.cau.cs.kieler.klodd.ui/src/de/cau/cs/kieler/klodd/ui/messages.properties (revision 0) @@ -1,16 +0,0 @@ -klodd.ui.0=Preferences for the KIELER data flow layouters. -klodd.ui.1=KLoDD Hierarchical Layouter -klodd.ui.2=Minimal distance between layout elements: -klodd.ui.3=KLoDD Orthogonal Layouter -klodd.ui.4=Minimal distance between layout elements: -klodd.ui.5=Cycle remover module: -klodd.ui.6=DFS cycle removal -klodd.ui.7=Greedy cycle removal -klodd.ui.8=Layer assignment module: -klodd.ui.9=Longest path layering -klodd.ui.10=Balanced layering -klodd.ui.11=Number of passes for crossing reduction: -klodd.ui.12=Edge routing module: -klodd.ui.13=Sorting method -klodd.ui.14=Topological numbering method -klodd.ui.15=Favor balanced node positioning over diagram size Index: plugins/de.cau.cs.kieler.klodd.ui/src/de/cau/cs/kieler/klodd/ui/package-info.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.ui/src/de/cau/cs/kieler/klodd/ui/package-info.java (revision d64f8376ecb2f5ba7914d76004fc6003b9ffb76c) +++ plugins/de.cau.cs.kieler.klodd.ui/src/de/cau/cs/kieler/klodd/ui/package-info.java (revision 0) @@ -1,18 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ - -/** - * Base package of the KLoDD user interface. - */ -package de.cau.cs.kieler.klodd.ui; Index: plugins/de.cau.cs.kieler.klodd.ui/src/de/cau/cs/kieler/klodd/ui/preferences/KloddLayouterPreferencePage.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.ui/src/de/cau/cs/kieler/klodd/ui/preferences/KloddLayouterPreferencePage.java (revision e40423edcc5feed14a967696da575e26a251c7db) +++ plugins/de.cau.cs.kieler.klodd.ui/src/de/cau/cs/kieler/klodd/ui/preferences/KloddLayouterPreferencePage.java (revision 0) @@ -1,130 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.ui.preferences; - -import org.eclipse.jface.preference.BooleanFieldEditor; -import org.eclipse.jface.preference.FieldEditor; -import org.eclipse.jface.preference.FieldEditorPreferencePage; -import org.eclipse.jface.preference.IntegerFieldEditor; -import org.eclipse.jface.preference.RadioGroupFieldEditor; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Group; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPreferencePage; - -import de.cau.cs.kieler.klodd.hierarchical.HierarchicalDataflowLayoutProvider; -import de.cau.cs.kieler.klodd.ui.KloddUIPlugin; -import de.cau.cs.kieler.klodd.ui.Messages; - -/** - * Preference page for all KLoDD layout algorithms. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class KloddLayouterPreferencePage extends FieldEditorPreferencePage implements - IWorkbenchPreferencePage { - - /** maximal number of crossing reduction iterations. */ - private static final int MAX_CROSSRED = 999; - /** maximal number of characters in the crossing reduction iterations text. */ - private static final int MAX_CROSSRED_CHAR = 3; - - /** - * Creates the preference page. - */ - public KloddLayouterPreferencePage() { - super(FLAT); - setDescription(Messages.getString("klodd.ui.0")); //$NON-NLS-1$ - } - - /** - * {@inheritDoc} - */ - @Override - public void createFieldEditors() { - // options group for hierarchical layouter - Composite parent = getFieldEditorParent(); - Group hieraGroup = new Group(parent, SWT.NONE); - hieraGroup.setText(Messages.getString("klodd.ui.1")); //$NON-NLS-1$ - - FieldEditor balanceEditor = new BooleanFieldEditor( - HierarchicalDataflowLayoutProvider.PREF_BALANCE_VS_SIZE, Messages - .getString("klodd.ui.15"), hieraGroup); - addField(balanceEditor); - - FieldEditor cycleRemEditor = new RadioGroupFieldEditor( - HierarchicalDataflowLayoutProvider.PREF_CYCLE_REM, - Messages.getString("klodd.ui.5"), 1, new String[][] {//$NON-NLS-1$ - {Messages.getString("klodd.ui.6"), //$NON-NLS-1$ - HierarchicalDataflowLayoutProvider.VAL_DFS_CYCLE_REM }, - {Messages.getString("klodd.ui.7"), //$NON-NLS-1$ - HierarchicalDataflowLayoutProvider.VAL_GREEDY_CYCLE_REM } }, hieraGroup, - false); - addField(cycleRemEditor); - - FieldEditor layerAssEditor = new RadioGroupFieldEditor( - HierarchicalDataflowLayoutProvider.PREF_LAYER_ASS, - Messages.getString("klodd.ui.8"), 1, new String[][] {//$NON-NLS-1$ - {Messages.getString("klodd.ui.9"), //$NON-NLS-1$ - HierarchicalDataflowLayoutProvider.VAL_LONGP_LAYER_ASS }, - {Messages.getString("klodd.ui.10"), //$NON-NLS-1$ - HierarchicalDataflowLayoutProvider.VAL_BAL_LAYER_ASS } }, hieraGroup, - false); - addField(layerAssEditor); - - FieldEditor edgeRouteEditor = new RadioGroupFieldEditor( - HierarchicalDataflowLayoutProvider.PREF_LAYER_EDGEROUTER, Messages - .getString("klodd.ui.12"), 1, new String[][] {//$NON-NLS-1$ - {Messages.getString("klodd.ui.13"), //$NON-NLS-1$ - HierarchicalDataflowLayoutProvider.VAL_SORT_LAYER_EDGEROUTER }, - {Messages.getString("klodd.ui.14"), //$NON-NLS-1$ - HierarchicalDataflowLayoutProvider.VAL_TOPO_LAYER_EDGEROUTER } }, - hieraGroup, false); - addField(edgeRouteEditor); - - Composite crossRedPassesParent = new Composite(hieraGroup, SWT.NONE); - IntegerFieldEditor crossRedPassesEditor = new IntegerFieldEditor( - HierarchicalDataflowLayoutProvider.PREF_CROSSRED_PASSES, Messages - .getString("klodd.ui.11"), crossRedPassesParent, //$NON-NLS-1$ - MAX_CROSSRED_CHAR); - crossRedPassesEditor.setValidRange(1, MAX_CROSSRED); - crossRedPassesParent.setLayout(new GridLayout(2, false)); - crossRedPassesParent.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1)); - addField(crossRedPassesEditor); - - hieraGroup.setLayout(new GridLayout(1, false)); - parent.setLayout(new FillLayout()); - - // options group for orthogonal layouter - // Group orthoGroup = new Group(this.getFieldEditorParent(), SWT.NONE); - // orthoGroup.setText(Messages.getString("klodd.ui.3")); //$NON-NLS-1$ - // - // orthoGroup.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, - // 1, 1)); - // orthoGroup.setLayout(new GridLayout(2, false)); - } - - /** - * {@inheritDoc} - */ - public void init(final IWorkbench workbench) { - setPreferenceStore(KloddUIPlugin.getDefault().getPreferenceStore()); - } - -} Index: plugins/de.cau.cs.kieler.klodd.ui/src/de/cau/cs/kieler/klodd/ui/preferences/PreferenceInitializer.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.ui/src/de/cau/cs/kieler/klodd/ui/preferences/PreferenceInitializer.java (revision e40423edcc5feed14a967696da575e26a251c7db) +++ plugins/de.cau.cs.kieler.klodd.ui/src/de/cau/cs/kieler/klodd/ui/preferences/PreferenceInitializer.java (revision 0) @@ -1,48 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ -package de.cau.cs.kieler.klodd.ui.preferences; - -import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; -import org.eclipse.jface.preference.IPreferenceStore; - -import de.cau.cs.kieler.klodd.hierarchical.HierarchicalDataflowLayoutProvider; -import de.cau.cs.kieler.klodd.ui.KloddUIPlugin; - -/** - * Initializer for the KLoDD layouter plugin preferences. - * - * @kieler.rating 2009-12-11 proposed yellow msp - * @author msp - */ -public class PreferenceInitializer extends AbstractPreferenceInitializer { - - /** - * {@inheritDoc} - */ - public void initializeDefaultPreferences() { - IPreferenceStore store = KloddUIPlugin.getDefault().getPreferenceStore(); - - // initialize options for hierarchical layout - store.setDefault(HierarchicalDataflowLayoutProvider.PREF_CYCLE_REM, - HierarchicalDataflowLayoutProvider.VAL_GREEDY_CYCLE_REM); - store.setDefault(HierarchicalDataflowLayoutProvider.PREF_LAYER_ASS, - HierarchicalDataflowLayoutProvider.VAL_BAL_LAYER_ASS); - store.setDefault(HierarchicalDataflowLayoutProvider.PREF_LAYER_EDGEROUTER, - HierarchicalDataflowLayoutProvider.VAL_TOPO_LAYER_EDGEROUTER); - store.setDefault(HierarchicalDataflowLayoutProvider.PREF_CROSSRED_PASSES, - HierarchicalDataflowLayoutProvider.DEF_CROSSRED_PASSES); - store.setDefault(HierarchicalDataflowLayoutProvider.PREF_BALANCE_VS_SIZE, true); - } - -} Index: plugins/de.cau.cs.kieler.klodd.ui/src/de/cau/cs/kieler/klodd/ui/preferences/package-info.java =================================================================== diff -u -N --- plugins/de.cau.cs.kieler.klodd.ui/src/de/cau/cs/kieler/klodd/ui/preferences/package-info.java (revision d64f8376ecb2f5ba7914d76004fc6003b9ffb76c) +++ plugins/de.cau.cs.kieler.klodd.ui/src/de/cau/cs/kieler/klodd/ui/preferences/package-info.java (revision 0) @@ -1,18 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://www.informatik.uni-kiel.de/rtsys/kieler/ - * - * Copyright 2009 by - * + Christian-Albrechts-University of Kiel - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - * See the file epl-v10.html for the license text. - */ - -/** - * Preferences for the KLoDD layouters. - */ -package de.cau.cs.kieler.klodd.ui.preferences;