/* * Created on Jul 14, 2004 */ package com.realpersist.gef.layout; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.draw2d.graph.DirectedGraph; import org.eclipse.draw2d.graph.Edge; import org.eclipse.draw2d.graph.EdgeList; import org.eclipse.draw2d.graph.Node; import org.eclipse.draw2d.graph.NodeList; /** * Creates dummy edges between nodes, to be used with NodeJoiningDirectedGraphLayout * @author Phil Zoio */ public class ClusterEdgeCreator { //sets up maximum depth of recursion to set up initial cluster list private static final int INITIAL_RECURSION_DEPTH = 3; NodeList nodeList; EdgeList edgeList; DirectedGraph graph; List edgesAdded; List encountered = new ArrayList(); List clusters = new ArrayList(); Cluster currentCluster = null; /** * @param graph */ public ClusterEdgeCreator() { super(); } public void visit(DirectedGraph graph) { try { this.graph = graph; this.nodeList = graph.nodes; this.edgeList = graph.edges; edgesAdded = new ArrayList(); //iterate through all of the nodes in the node list for (Iterator iter = nodeList.iterator(); iter.hasNext();) { Node node = (Node) iter.next(); //check whether we have already come across this node if (!encountered.contains(node)) { //create a new cluster for this node currentCluster = new Cluster(); clusters.add(currentCluster); encountered.add(node); currentCluster.set.add(node); //System.out.println("Adding to NEW cluster: " + node + ", cluster: " + currentCluster); // recursively add any other nodes reachable from it int depth = INITIAL_RECURSION_DEPTH; recursivelyAddToCluster(node, depth); } else { //System.out.println("Already encountered: " + node); } } //System.out.println("Clusters: "); for (Iterator iter = clusters.iterator(); iter.hasNext();) { Cluster cluster = (Cluster) iter.next(); //System.out.println(cluster); } coalesceRemainingClusters(); //System.out.println(""); joinClusters(); } catch (RuntimeException e) { e.printStackTrace(); throw e; } } /** * If recursion fails to join all the remaining */ private void coalesceRemainingClusters() { } /** * Joins the clusters together */ private void joinClusters() { if (clusters.size() > 1) { Node sourceNode = null; Node targetNode = null; //add an edge from each successive cluster to next for (Iterator iter = clusters.iterator(); iter.hasNext();) { Cluster cluster = (Cluster) iter.next(); if (sourceNode != null) { //use first node in set as target node targetNode = (Node) cluster.set.get(0); newDummyEdge(sourceNode, targetNode); } //set up source node for the next iteration using last node in // set sourceNode = (Node) cluster.set.get(cluster.set.size() - 1); } } } private void recursivelyAddToCluster(Node node, int depth) { if (depth > 3) return; else { depth++; EdgeList incoming = node.incoming; for (Iterator iter = incoming.iterator(); iter.hasNext();) { Edge edge = (Edge) iter.next(); Node incomingNode = edge.source; if (!encountered.contains(incomingNode)) { encountered.add(incomingNode); currentCluster.set.add(incomingNode); //System.out.println("Adding to current cluster: " + incomingNode + ", cluster: " + currentCluster); recursivelyAddToCluster(incomingNode, depth); } else { //System.out.println("Already encountered: " + incomingNode); } } EdgeList outgoing = node.outgoing; for (Iterator iter = outgoing.iterator(); iter.hasNext();) { Edge edge = (Edge) iter.next(); Node outgoingNode = edge.target; if (!encountered.contains(outgoingNode)) { encountered.add(outgoingNode); currentCluster.set.add(outgoingNode); //System.out.println("Adding to current cluster: " + outgoingNode + ", cluster: " + currentCluster); recursivelyAddToCluster(outgoingNode, depth); } else { //System.out.println("Already encountered: " + outgoingNode); } } } } /** * creates a new dummy edge to be used in the graph */ private Edge newDummyEdge(Node sourceNode, Node targetNode) { boolean addedEdge; DummyEdgePart edgePart = new DummyEdgePart(); Edge edge = new Edge(edgePart, sourceNode, targetNode); edge.weight = 2; //add the new edge to the edge list edgeList.add(edge); targetNode = sourceNode; addedEdge = true; return edge; } /** * Very thin wrapper around List */ private class Cluster { List set = new ArrayList(); public String toString() { return set.toString(); } } }