All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.gluebooster.java.booster.basic.container.BoostedNodeUtils Maven / Gradle / Ivy

package net.sf.gluebooster.java.booster.basic.container;



import java.awt.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.swing.event.ChangeListener;

import org.apache.commons.lang3.tuple.Pair;

import edu.uci.ics.jung.graph.DirectedSparseMultigraph;
import edu.uci.ics.jung.graph.Graph;
import net.sf.gluebooster.java.booster.basic.math.graph.BoostedNodeGraph;
import net.sf.gluebooster.java.booster.basic.math.graph.GraphDisplayConfiguration;
import net.sf.gluebooster.java.booster.basic.math.graph.JungGraphLayouter;
import net.sf.gluebooster.java.booster.basic.meta.DocumentationContext;
import net.sf.gluebooster.java.booster.basic.meta.ObjectAnalyzer;
import net.sf.gluebooster.java.booster.essentials.utils.Check;
import net.sf.gluebooster.java.booster.essentials.utils.ContainerBoostUtils;

/**
 * Utility methods for boosted nodes.
 * 
 * @defaultParamText node the node to inspect/update
 * @defaultParamText node2 the second node
 * @defaultParamText addBeforeThisPoint the new node should be added before this point
 * @defaultParamText listener may be null
 * @defaultParamText name the name of the node
 * @author CBauer
 * 
 */
public class BoostedNodeUtils {
 

	/**
	 * Adds a new focus point.
	 * 
	 * @return the created point
	 */
	public static BoostedNode addZoomInFocusPoint(BoostedNode node, BoostedNode addBeforeThisPoint){

		BoostedNode focusPoint = node.createZoomInFocus();
		focusPoint.setZoomOut(Pair.of(node, focusPoint), null);
		ListallPoints = node.getAllZoomInFocus();
		if (addBeforeThisPoint == null)
			allPoints.add(focusPoint);
		else { 
			int index = allPoints.indexOf(addBeforeThisPoint);
			if (index == -1){
				BoostedNode focus = addBeforeThisPoint.getZoomOut(null).getRight();
				index = allPoints.indexOf(focus);
				if (index == -1 )
					throw new IllegalStateException("did not find " + addBeforeThisPoint + " or " + focus + " in list " + allPoints);
			}
			node.getAllZoomInFocus().add(index, focusPoint);
		}
		return focusPoint;
	}
	
	/**
	 * Creates a new zoom in node
	 * 
	 * @param name
	 *            the name of the node
	 * @return the created node
	 */
	@SuppressWarnings("unchecked")
	private static BoostedNode createZoomInNode(BoostedNode node, Object name,
			BoostedNode addBeforeThisPoint) {
		BoostedNode resultNode;

		if (node == null) {
			resultNode = new SimpleBoostedNode();
		} else {
			resultNode = node.createZoomInObject();
		}

		if (name != null)
			resultNode.getAttributes().setName(name);

		
		if (node != null) {
			addZoomInNode(node, resultNode, addBeforeThisPoint);
		}

		return resultNode;
	}
	
	/**
	 * Add a node as zoom-in of a parent node
	 * 
	 * @param parent
	 *            the zoom-out-node of the new node
	 * @param zoomIn
	 *            the node after the zooming-in from the parent
	 * @return the zoomInFocusPoint for the zoomIn
	 */
	public static BoostedNode addZoomInNode(BoostedNode parent, BoostedNode zoomIn, BoostedNode addBeforeThisPoint) {
		BoostedNode zoomPoint = addZoomInFocusPoint(parent, addBeforeThisPoint);
		parent.setZoomInFocus(zoomPoint, zoomIn);
		Object name = zoomPoint.getAttributes().getName();
		if (name != null)
			zoomPoint.getAttributes().setName("zoom into " + name);

		zoomIn.setZoomOut(Pair.of(parent, zoomPoint), null);

		return zoomPoint;
	}

	/**
	 * Creates a node used to zoom-in from another node .
	 * 
	 * @return the created node
	 */
	public static BoostedNode createZoomInNode(BoostedNode node,
			ChangeListener listener, Object name, BoostedNode addBeforeThisPoint) {
		BoostedNode resultNode = createZoomInNode(node, name,
				addBeforeThisPoint);

		if (listener != null)
			resultNode.addChangeListener(listener);
		
		return resultNode;
	}

	/**
	 * Creates a node used to zoom-in from another node .
	 * 
	 * @param context
	 *            is queried for a change listener
	 * @return the created node
	 */
	public static BoostedNode createZoomInNode(BoostedNode node, DocumentationContext context, Object name, BoostedNode addBeforeThisPoint) throws Exception {
		ChangeListener listener = null;
		if (context != null) {
			listener = context.getChangeListener();
		}
		return createZoomInNode(node, listener, name, addBeforeThisPoint);
	}

	/**
	 * Create a zoom in node, using the listener of the node
	 * 
	 * @return the created node
	 */
	public static BoostedNode createZoomInNodeUseParentListener(
			BoostedNode node, Object name, BoostedNode addBeforeThisPoint) {
		Check.notNull(node, "node");
		
		
		BoostedNode resultNode = createZoomInNode(node, name,
				addBeforeThisPoint);

		resultNode.addChangeListener(node.getChangeListeners());
		
		return resultNode;
	}
	
	/**
	 * Compute the successors of a node.
	 * 
	 * @return the successors
	 */
	public static List getSuccessors(BoostedNode node){
		List result = new ArrayList();
		for(BoostedNode outPoint:  node.getOutPoints()){
			for(BoostedNode inPoint: node.getSuccessorInPoints(outPoint)){
				BoostedNode resultNode = inPoint.getZoomOut(null).getLeft();
				if (resultNode == null)
					throw new IllegalStateException("Inpoint without zoom out: " + inPoint);
				result.add(resultNode);
			}
		}
		return result;
	}

	/**
	 * Gets the successor of a node.
	 * 
	 * @param node
	 *            must have at most one successor
	 * @return null if no successor found
	 */
	public static BoostedNode getSuccessor(BoostedNode node) {
		List result = getSuccessors(node);
		if (result == null || result.isEmpty()) {
			return null;
		} else if (result.size() > 1) {
			throw new IllegalStateException("There should only be one successor: " + result);
		} else {
			return result.get(0);
		}
	}

	/**
	 * Compute the predecessors of a node.
	 * 
	 * @return the predecessors
	 */
	public static List getPredecessors(BoostedNode node){
		List result = new ArrayList();
		for (BoostedNode inPoint : node.getInPoints()) {
			for (BoostedNode outPoint : node.getPredecessorOutPoints(inPoint)) {
				BoostedNode resultNode = outPoint.getZoomOut(null).getLeft();
				if (resultNode == null)
					throw new IllegalStateException(
							"Outpoint without zoom out: " + outPoint);
				result.add(resultNode);
			}
		}
		return result;
	}
	
	/**
	 * Compute the zoom in nodes of a node.
	 * 
	 * @return the found nodes
	 */
	public static List getZoomInNodes(BoostedNode node){
		List result = new ArrayList();
		for(BoostedNode focusPoint:  node.getAllZoomInFocus()){
			BoostedNode resultNode = node.getZoomIn(focusPoint, null);
			if (resultNode == null)
				throw new IllegalStateException("No zoom in for: "
						+ node
						+ " focus "
						+ focusPoint
						+ "\nCheck of all focus points: \n"
						+ ContainerBoostUtils.whyIsElementNotInCollection(
								node.getAllZoomInFocus(), focusPoint));
			
				result.add(resultNode);
		}
		return result;
	}
	
	/**
	 * Gets all nodes of a graph that are connected with a given node.
	 * 
	 * @param nodeOfGraph
	 *            one node of the graph
	 * @return all connected nodes
	 */
	public static Set getAllNodesOfGraph(BoostedNode nodeOfGraph) {
		HashSet result = new HashSet();
		getAllNodesOfGraph(nodeOfGraph, result);
		return result;
	}

	/**
	 * Gets all nodes of a graph that are connected with a given node.
	 * 
	 * @param nodeOfGraph
	 *            one node of the graph
	 * @param result
	 *            all nodes are added to the result
	 */
	private static void getAllNodesOfGraph(BoostedNode nodeOfGraph,
			Set result) {
		if (!result.contains(nodeOfGraph)) {
			result.add(nodeOfGraph);
			for (BoostedNode successor : getSuccessors(nodeOfGraph))
				getAllNodesOfGraph(successor, result);
			for (BoostedNode predecessor : getPredecessors(nodeOfGraph))
				getAllNodesOfGraph(predecessor, result);

		}
	}


	/**
	 * Add an edge to the graph
	 * 
	 * @param predecessor
	 *            the starting point of the edge
	 * @param successor
	 *            the end point of the edge
	 */
	public static void addEdge(BoostedNode predecessor, BoostedNode successor)
			throws Exception {
		BoostedNode outPoint = addOutPoint(predecessor);
		addEdgeFromOutpointToNode(predecessor, outPoint, successor);
	
	}


	/**
	 * Add multiple edges from some nodes to another node
	 * 
	 * @param predecessors
	 *            the edges will start there
	 * @param inPoint
	 *            the edges will end in this point
	 * @param successor
	 *            contains the in-point
	 */
	public static void addEdgeFromNodesToInpoint(
			Collection predecessors, BoostedNode inPoint,
			BoostedNode successor) throws Exception {
		for (BoostedNode predecessor : predecessors) {
			addEdgeFromNodeToInpoint(predecessor, inPoint, successor);
		}
	}


	/**
	 * Adds an edge from a node to a given in-point
	 * 
	 * @param predecessor
	 *            the start of the edge
	 * @param inPoint
	 *            the end-point of the edge
	 * @param successor
	 *            contains the inPoint
	 */
	public static void addEdgeFromNodeToInpoint(BoostedNode predecessor,
			BoostedNode inPoint, BoostedNode successor) throws Exception {
		BoostedNode outPoint = addOutPoint(predecessor);
		addEdgeFromOutpointToInpoint(predecessor, outPoint, inPoint, successor);
	
	}


	/**
	 * Add a edge from a give out-point to a given in-point. TODO is it possible to get the predecessor and successor from the point?
	 * 
	 * @param predecessor
	 *            contains the out-point
	 * @param outPoint
	 *            start of the edge
	 * @param inPoint
	 *            end of the edge
	 * @param successor
	 *            contains the in-point.
	 */
	public static void addEdgeFromOutpointToInpoint(BoostedNode predecessor,
			BoostedNode outPoint, BoostedNode inPoint, BoostedNode successor)
			throws Exception {
	
		predecessor.addOutgoingEdge(outPoint, inPoint);
		successor.addIngoingEdge(outPoint, inPoint);
	
		// checkPredecessorSuccessor(predecessor);
		// checkPredecessorSuccessor(successor);
	}


	/**
	 * Creates a new inPoint in the successor and connects the outPoint with the inPoint
	 * 
	 * @param predecessor
	 *            the predecessor of the edge
	 * @param outPoint
	 *            the start of the edge
	 * @param successor
	 *            the successor of the edge. Contains the outpoint
	 */
	public static void addEdgeFromOutpointToNode(BoostedNode predecessor,
			BoostedNode outPoint, BoostedNode successor) throws Exception {
		BoostedNode inPoint = addInPoint(successor);
		addEdgeFromOutpointToInpoint(predecessor, outPoint, inPoint, successor);
	
	}


	/**
	 * Creates a new inPoint in the successor and connects the outPoint with the inPoint
	 * 
	 * @param predecessor
	 *            contains the out-point
	 * @param outPoint
	 *            from this point the edges will start
	 * @param successors
	 *            the ends of the edges
	 */
	public static void addEdgeFromOutpointToNodes(BoostedNode predecessor,
			BoostedNode outPoint, Collection successors)
			throws Exception {
		for (BoostedNode successor : successors) {
			addEdgeFromOutpointToNode(predecessor, outPoint, successor);
		}
	}


	/**
	 * Add a new in-point to a node
	 * 
	 * @return the created in-point
	 */
	public static BoostedNode addInPoint(BoostedNode node) throws Exception {
	
		ArrayList inPoints = new ArrayList(
				node.getInPoints());
	
		BoostedNode inPoint = node.createInPoint();
		inPoint.setZoomOut(Pair.of(node, inPoint), null);
	
		inPoints.add(inPoint);
		((SimpleBoostedNode) node).setInPoints(inPoints);
		return inPoint;
	}


	/**
	 * Hack because of bug of BoostedNodeUtils
	 * 
	 * @return the out-point
	 * @throws Exception
	 */
	public static BoostedNode addOutPoint(BoostedNode node) throws Exception {
	
		// TODO BoostedNode.createOutPoint : modify the comment, that the
		// created point is automatically added to the out points
		// TODO modify the SimpleBoostedNode accordingly
		// TODO modify this method (and addInPoint) accordingly
		// TODO modify BoostedNode: add the setter for the outpoints
	
		ArrayList outPoints = new ArrayList(
				node.getOutPoints());
	
		BoostedNode outPoint = node.createOutPoint();
		outPoint.setZoomOut(Pair.of(node, outPoint), null);
	
		// node.getOutPoints().add(outPoint);
		outPoints.add(outPoint);
		((SimpleBoostedNode) node).setOutPoints(outPoints);
		return outPoint;
	}


	/**
	 * Computes all predecessors and their predecessors, etc..
	 * 
	 * @param node
	 *            the inspected node
	 * @param result
	 *            will contain all nodes from which the node can be reached.
	 */
	public static void addReachablePredecessors(BoostedNode node,
			Set result) {
		for (BoostedNode predecessor : BoostedNodeUtils
					.getPredecessors(node)) {
			if (!result.contains(predecessor)) {
				result.add(predecessor);
				addReachablePredecessors(predecessor, result);
			}
		}
	
	}


	/**
	 * Get all successors, the successors of the successors, etc.
	 * 
	 * @param node
	 *            the inspected node
	 * @param result
	 *            will contain all nodes that can be reached from the node.
	 */
	public static void addReachableSuccessors(BoostedNode node,
			Set result) {
		for (BoostedNode successor : BoostedNodeUtils.getSuccessors(node)) {
			if (!result.contains(successor)) {
				result.add(successor);
				addReachableSuccessors(successor, result);
			}
		}
	}


	/**
	 * Create a predecessor node.
	 * 
	 * @return the created node
	 * @throws Exception
	 */
	public static BoostedNode createPredecessor(BoostedNode node)
			throws Exception {
		return createPredecessor(node, null);
	}


	/**
	 * Creates a predecessor node for a given node.
	 * 
	 * Refactor into boostednodeutils
	 * 
	 * @param node
	 *            the starting point
	 * @param listener
	 *            will be added to the predecessor
	 * @return the created node
	 */
	public static BoostedNode createPredecessor(BoostedNode node,
			ChangeListener listener) throws Exception {
		BoostedNode predecessorNode = node.createPeer();
	
		addEdge(predecessorNode, node);
	
		if (listener != null)
			predecessorNode.addChangeListener(listener);
	
		// checkPredecessorSuccessor(node);
		// checkPredecessorSuccessor(predecessorNode);
	
		return predecessorNode;
	}


	/**
	 * Creates a simple boosted node with a given name.
	 * 
	 * @param name
	 *            the name of the node
	 * @return the created node
	 */
	public static  SimpleBoostedNode createSimpleBoostedNode(
			Name name) throws Exception {
		SimpleBoostedNode result = new SimpleBoostedNode();
		result.setName(name);
		return result;
	}


	/**
	 * Create a successor node
	 * 
	 * @return the created node
	 */
	public static BoostedNode createSuccessor(BoostedNode node)
			throws Exception {
		BoostedNode result = createSuccessor(node, null);
	
		return result;
	}


	/**
	 * Create a success node with listener. 
	 * 
	 * 
	 * @param listener
	 *            listener of the new node
	 * @return the created node
	 */
	public static BoostedNode createSuccessor(BoostedNode node,
			ChangeListener listener) throws Exception {
		BoostedNode successorNode = node.createPeer();
	
		BoostedNode inPoint = addInPoint(successorNode);
	
		BoostedNode outPoint = addOutPoint(node);
	
		successorNode.addIngoingEdge(outPoint, inPoint);
		node.addOutgoingEdge(outPoint, inPoint);
	
		if (listener != null)
			successorNode.addChangeListener(listener);
	
		// checkPredecessorSuccessor(node);
		// checkPredecessorSuccessor(successorNode);
	
		return successorNode;
	}

	/**
	 * Refactor into BoostedNodeUtils. A sink vertex in a directed graph is a
	 * vertex without outgoing edge. See
	 * http://en.wikipedia.org/wiki/Vertex_%28graph_theory%29
	 * 
	 * @param nodeOfGraph
	 *            the starting point
	 * @return the found sinks
	 */
	public static Set getAllSinkVertices(
			final BoostedNode nodeOfGraph) {
		HashSet result = new HashSet();
		for (BoostedNode node : BoostedNodeUtils
				.getAllNodesOfGraph(nodeOfGraph)) {
			if (BoostedNodeUtils.getSuccessors(node).isEmpty()) {
				result.add(node);
			}
		}
		return result;
	}

	/**
	 * Refactor into BoostedNodeUtils. A source vertex in a directed graph is a
	 * vertex without ingoing edge. See
	 * http://en.wikipedia.org/wiki/Vertex_%28graph_theory%29
	 * 
	 * @param nodeOfGraph
	 *            the starting point
	 * @return the found sources
	 */
	public static Set getAllSourceVertices(
			final BoostedNode nodeOfGraph) {
		HashSet result = new HashSet();
		for (BoostedNode node : BoostedNodeUtils
				.getAllNodesOfGraph(nodeOfGraph)) {
			if (BoostedNodeUtils.getPredecessors(node).isEmpty()) {
				result.add(node);
			}
		}
		return result;
	}

	/**
	 * Counts the number of ingoing edges
	 * 
	 * @param node
	 *            the inspected node
	 * @return the number
	 */
	public static long getIngoingEdgeCount(BoostedNode node) {
		long result = 0;
		for (BoostedNode inpoint : node.getInPoints()) {
			result += node.getPredecessorOutPoints(inpoint).size();
		}
	
		return result;
	}

	/*
	 * public static void removeDuplicateEdges(BoostedNode node){
	 * HashSet successors = new HashSet(); for
	 * (BoostedNode out : node.getOutPoints()) { for (BoostedNode in :
	 * node.getSuccessorInPoints(out)) { BoostedNode succ =
	 * in.getZoomOut(null).getLeft(); if(successors.contains(succ)){
	 * Refactor.removeEdge(node, out, in, succ); } else { successors.add(succ);
	 * } } }
	 * 
	 * HashSet predecessors = new HashSet(); for
	 * (BoostedNode in : node.getInPoints()) { for (BoostedNode out :
	 * node.getPredecessorOutPoints(in)) { BoostedNode pre =
	 * out.getZoomOut(null).getLeft(); if (predecessors.contains(pre)){
	 * Refactor.removeEdge(pre, out, in, node); } else { predecessors.add(pre);
	 * } } }
	 * 
	 * }
	 */
	
	/**
	 * Checks that there are no duplicate edges from/to this node
	 * 
	 * @param node
	 *            the node to be inspected
	 */
	public static void checkNoDuplicateEdges(BoostedNode node) {
		HashSet successors = new HashSet();
		for (BoostedNode out : node.getOutPoints()) {
			for (BoostedNode in : node.getSuccessorInPoints(out)) {
				BoostedNode succ = in.getZoomOut(null).getLeft();
				Check.isTrue(!successors.contains(succ), "duplicate successor "
						+ succ);
				successors.add(succ);
			}
		}
	
		HashSet predecessors = new HashSet();
		for (BoostedNode in : node.getInPoints()) {
			for (BoostedNode out : node.getPredecessorOutPoints(in)) {
				BoostedNode pre = out.getZoomOut(null).getLeft();
				Check.isTrue(!predecessors.contains(pre),
						"duplicate predecessor " + pre);
				predecessors.add(pre);
			}
		}
	
	}

	/**
	 * Checks that predecessors and successors are correctly connected to a node
	 */
	public static void checkPredecessorSuccessor(BoostedNode node) throws Exception{
	
		// check successors
		for (BoostedNode outPoint : node.getOutPoints()) {
			for (BoostedNode inPoint : node.getSuccessorInPoints(outPoint)) {
				Pair successorAndFocus = inPoint
						.getZoomOut(null);
				BoostedNode successor = successorAndFocus.getLeft();
				if (!successor.getPredecessorOutPoints(inPoint).contains(
						outPoint)) {
					throw new IllegalStateException(
							"successor in-point has no connection to node out-point");
				}
	
			}
		}
	
		// check predecessors
		for (BoostedNode inPoint : node.getInPoints()) {
			for (BoostedNode outPoint : node.getPredecessorOutPoints(inPoint)) {
				Pair predecessorAndFocus = outPoint
						.getZoomOut(null);
				BoostedNode predecessor = predecessorAndFocus.getLeft();
				if (!predecessor.getSuccessorInPoints(outPoint).contains(
						inPoint)) {
					throw new IllegalStateException(
							"predecessor out-point has no connection to node in-point");
				}
	
			}
		}
		
	}

	/**
	 * Replaces one node (used in edges) by another
	 * 
	 * @param from
	 *            the node that is replaced
	 * @param to
	 *            the replacement
	 */
	public static void redirectEdges(BoostedNode from, BoostedNode to)
			throws Exception {
		List replacement = Arrays.asList(to);
		redirectEdges(from, replacement, replacement);
	}

	/**
	 * Redirects all edges from a node.
	 * 
	 * @param fromThisNode the edges of this node are redirected
	 * @param inEdgeReplacements in-going edges are redirected to these nodes
	 * @param outEdgeReplacements out-going edges are redirected to these nodes
	 */
	public static void redirectEdges(BoostedNode fromThisNode, Collection inEdgeReplacements, Collection outEdgeReplacements)
			throws Exception {
		// redirect in-Points
		for (BoostedNode inPoint : fromThisNode.getInPoints()) {
			for (BoostedNode outPoint : new ArrayList(fromThisNode.getPredecessorOutPoints(inPoint))) {
				// use a new list, because the list may change dynamically

				BoostedNode predecessorNode = outPoint.getZoomOut(null).getKey();

				removeEdge(predecessorNode, outPoint, inPoint, fromThisNode);
				addEdgeFromOutpointToNodes(predecessorNode, outPoint, inEdgeReplacements);

			}
			removeInPoint((SimpleBoostedNode) fromThisNode, inPoint);
		}

		// checkPredecessorSuccessor(node);

		// redirect out-Points
		for (BoostedNode outPoint : fromThisNode.getOutPoints()) {
			for (BoostedNode inPoint : new ArrayList(fromThisNode.getSuccessorInPoints(outPoint))) {
				// use a new list, because the list may change dynamically

				BoostedNode successorNode = inPoint.getZoomOut(null).getKey();
				// checkPredecessorSuccessor(successorNode);

				removeEdge(fromThisNode, outPoint, inPoint, successorNode);
				addEdgeFromNodesToInpoint(outEdgeReplacements, inPoint, successorNode);

			}
			removeOutPoint((SimpleBoostedNode) fromThisNode, outPoint);
		}

	}

	/**
	 * 
	 * Replaces the node by a subgraph. The nodes of the subgraph are changed.
	 * 
	 * TODO refactor this method and check the structure. remove the in and out point mappings.
	 * 
	 * @param node
	 * @param replaceBy
	 *            may be empty or null, then the node is removed and its pre- and successors are connected
	 */
		public static void replace(BoostedNode node, BoostedNodeGraph replaceBy)
				throws Exception {
	
			// if (replaceBy.getAllVertices().isEmpty()){
			// throw new IllegalStateException("replaceBy is empty");
			// }
			
			// checkPredecessorSuccessor(node);
	
			// Cache the predecessors and successors before they may be changed
			// during the following algorithm
			Collection nodePredecessors = BoostedNodeUtils
					.getPredecessors(node);
			Collection nodeSuccessors = BoostedNodeUtils
					.getSuccessors(node);
	
			boolean emptyReplacement = (replaceBy == null) || replaceBy.isEmpty();
			// if the replaceBy graph is empty the predecessors and successors of
			// the node must be connected directly.
			// To prevent that edges are duplicate count the edges when redirecting
			// the in-points and only insert additional edges of the out-points when
			// there are more
	
			Collection newSuccessors;
			if (emptyReplacement) {
				newSuccessors = nodeSuccessors;
			} else {
				newSuccessors = replaceBy.getAllSourceVertices();
			}
	
			Collection newPredecessors;
			if (emptyReplacement) {
				newPredecessors = Collections.EMPTY_SET;// because the connections have already been set // nodePredecessors;
			} else {
				newPredecessors = replaceBy.getAllSinkVertices();
			}
	
			CountingMap> addedEdgeCount = new CountingMap>();
	
		redirectEdges(node, newSuccessors, newPredecessors);
		// //redirect in-Points
		// for (BoostedNode inPoint: node.getInPoints()){
		// for (BoostedNode outPoint : new ArrayList(
		// node.getPredecessorOutPoints(inPoint))) {
		// // use a new list, because the list may change dynamically
		//
		// BoostedNode predecessorNode = outPoint.getZoomOut(null)
		// .getKey();
		//
		// removeEdge(predecessorNode, outPoint, inPoint, node);
		// addEdgeFromOutpointToNodes(predecessorNode, outPoint,
		// newSuccessors);
		//
		// }
		// removeInPoint((SimpleBoostedNode) node, inPoint);
		// }
		//
		// // checkPredecessorSuccessor(node);
		//
		// // redirect out-Points
		// for (BoostedNode outPoint : node.getOutPoints()) {
		// for (BoostedNode inPoint : new ArrayList(
		// node.getSuccessorInPoints(outPoint))) {
		// // use a new list, because the list may change dynamically
		//
		// BoostedNode successorNode = inPoint.getZoomOut(null).getKey();
		// // checkPredecessorSuccessor(successorNode);
		//
		// removeEdge(node, outPoint, inPoint, successorNode);
		// addEdgeFromNodesToInpoint(newPredecessors, inPoint,
		// successorNode);
		//
		// }
		// removeOutPoint((SimpleBoostedNode) node, outPoint);
		// }
	
	
		}

	// check the path to the jfxrt and if it is available in all java versions
	// move into basic pom
	// mvn install:install-file -Dfile="C:\Program Files\Java\jdk1.7.0_07\jre\lib\jfxrt.jar" -DgroupId=com.oracle -DartifactId=javafx -Dversion=2.0
	// -Dpackaging=jar
	
	// add to root pom:
	// svn can be installed using sliksvn
	// gpg is installed looking for GnuPG
	// After the installation the secret key is to be imported via gpg --allow-secret-key-import --import private.key
	
	/**
	 * Create a directed graph from a graph.
	 * 
	 * Refactor into JungGraphBoostUtils
	 * 
	 * @param graph
	 *            the original graph.
	 * @return the created graph
	 */
	public static Graph createDefaultDirectedGraph(
			BoostedNodeGraph graph) {
	
		DirectedSparseMultigraph result = new DirectedSparseMultigraph<>();
	
		Set nodes = graph.getAllVertices();
	
		int counter = 0;
		// Add the vertices
		for (BoostedNode node : nodes) {
			result.addVertex(node);
		}
	
		// predecessors are sufficient, otherwise all edges would be duplicated
		for (BoostedNode node : nodes) {
			for (BoostedNode predecessor : BoostedNodeUtils
					.getPredecessors(node)) {
				// result.addVertex(inPoint);
				result.addEdge("edge-" + counter++ /*
													 * + " from " + predecessor
													 * + " to " + node
													 */, predecessor, node);
			}
		}
	
	
		return result;
	}

	/**
	 * Counts the number of outgoing edges.
	 * 
	 * @param node
	 *            the inspected node
	 * @return the number
	 */
	public static long getOutgoingEdgeCount(BoostedNode node) {
		long result = 0;
		for (BoostedNode outpoint : node.getOutPoints()) {
			result += node.getSuccessorInPoints(outpoint).size();
		}
	
		return result;
	}

	/**
	 * Refactor into BoostedNode as toStructureString in SimpleBoostedNode. Display the structure of a node as string
	 * 
	 * @return out-points and in-points mappings
	 */
	public static String getStructureString(BoostedNode node) throws Exception {
		StringBuilder result = new StringBuilder();
		result.append(node.getAttributes().getName()).append("\n");
		result.append("out: ")
				.append(ObjectAnalyzer
						.getPrivateField(node, "outPointsMapping"))
				.append("\n");
		result.append("in: ")
				.append(ObjectAnalyzer.getPrivateField(node, "inPointsMapping"))
				.append("\n");
		return result.toString();
	}

	/**
	 * If the node has multiple edges to the same successor, only one will remain
	 * 
	 * @param node
	 *            the inspected node
	 */
	public static void removeDuplicateEdges(BoostedNode node) {
		List successors = BoostedNodeUtils.getSuccessors(node);
		HashSet successorSet = new HashSet(successors);
		if (successorSet.size() < successors.size()) {
			CountingMap counter = new CountingMap();
			for (BoostedNode successor : successors) {
				counter.increment(successor);
			}
			for (BoostedNode outpoint : node.getOutPoints()) {
				List successorInPoints = node
						.getSuccessorInPoints(outpoint);
				// iterator over a new list because otherwise a
				// ConcurrentModificationException can occur
				for (BoostedNode inpoint : new ArrayList(
						successorInPoints)) {
					BoostedNode successor = inpoint.getZoomOut(null).getLeft();
					counter.decrement(successor);
					if (counter.get(successor).longValue() > 0) {
						successorInPoints.remove(inpoint);
						successor.getPredecessorOutPoints(inpoint).remove(
								outpoint);
					}
				}
				
			}
	
	
		}
	
	}

	/**
	 * Removes one edge between the specified points
	 * 
	 * @param predecessor
	 *            the predecessor node
	 * @param predecessorOutpoint
	 *            the out-point of the predecessor
	 * @param successorInpoint
	 *            the in-point of the successor
	 * @param successor
	 *            the successor node
	 */
	public static void removeEdge(BoostedNode predecessor,
			BoostedNode predecessorOutpoint, BoostedNode successorInpoint,
			BoostedNode successor) {
		if (!predecessor.getSuccessorInPoints(predecessorOutpoint).remove(
				successorInpoint)) {
			throw new IllegalStateException(
					"There is no connection from the predecessorOutpoint  to the successorInpoint");
		}
		if (!successor.getPredecessorOutPoints(successorInpoint).remove(
				predecessorOutpoint)) {
			throw new IllegalStateException(
					"There is no connection to the successorInpoint from the predecessorOutpoint  ");
		}
	
	}

	/**
	 * Removes one in-point from a given node.
	 * 
	 * @param inPoint
	 *            the point to be removed
	 */
	private static void removeInPoint(SimpleBoostedNode node,
			BoostedNode inPoint) {
	
		ArrayList newInPoints = new ArrayList(
				node.getInPoints());
		newInPoints.remove(inPoint);
		node.setInPoints(newInPoints);
	
	}

	/**
	 * Removes one out-point from a given node.
	 * 
	 * @param outPoint
	 *            the point to be removed
	 */
	private static void removeOutPoint(SimpleBoostedNode node,
			BoostedNode outPoint) {
	
		ArrayList newOutPoints = new ArrayList(
				node.getOutPoints());
		newOutPoints.remove(outPoint);
		node.setOutPoints(newOutPoints);
	
	}

	// check the path to the jfxrt and if it is available in all java versions
	// move into basic pom
	// mvn install:install-file -Dfile="C:\Program Files\Java\jdk1.7.0_07\jre\lib\jfxrt.jar" -DgroupId=com.oracle -DartifactId=javafx -Dversion=2.0
	// -Dpackaging=jar
	
	// add to root pom:
	// svn can be installed using sliksvn
	// gpg is installed looking for GnuPG
	// After the installation the secret key is to be imported via gpg --allow-secret-key-import --import private.key
	
	/**
	 * Refactor into JungGraphBoostUtils. Creates a graphical display of a given
	 * graph.
	 * 
	 * @param boostedNodeGraph
	 *            the graph
	 * @param displayConfiguration
	 *            the configuration of the display
	 * @param overlappingAllowedFlag
	 *            may the display have overlapping nodes
	 * @return the display
	 */
	public static  Component createOverviewGraphComponent(
			BoostedNodeGraph boostedNodeGraph,
			// final int vertexDetailDisplayLevel,
			/* final boolean displayVertexValueInsteadOfName, */
			final GraphDisplayConfiguration displayConfiguration) throws Exception {
		Graph graph = createDefaultDirectedGraph(boostedNodeGraph);
	
		JungGraphLayouter layouter = new JungGraphLayouter();
		layouter.setConfiguration(displayConfiguration);
		layouter.setGraph(graph);
		return layouter.createLayoutComponent();
	}

	/**
	 * Returns the first inpoint. If no inpoint is available, a new point is created.
	 * 
	 * @return the in-point
	 */
	public static BoostedNode getFirstInpointOrCreate(BoostedNode node) throws Exception {
		List inPoints = node.getInPoints();
		if (inPoints.isEmpty()) {
			return node.createInPoint();
		} else {
			return inPoints.get(0);
		}

	}

	/**
	 * Are all nodes parallel to each other
	 * 
	 * @param nodes
	 *            the nodes to be inspected return true iff parallel
	 * @return true iff parallel
	 */
	public static boolean isParallel(Collection nodes) {
		HashSet copy = new HashSet(nodes);
		for (BoostedNode node : nodes) {
			copy.remove(node);
			if (!isParallel(node, copy)) {
				return false;
			}
		}
		return true;
	}

	/**
	 * Is a node parallel to the other nodes
	 * 
	 * @param nodes
	 *            the other nodes return true iff parallel
	 * @return true iff parallel
	 */
	public static boolean isParallel(BoostedNode node, Collection nodes) {
		for (BoostedNode node2 : nodes) {
			if (!isParallel(node, node2)) {
				return false;
			}
		}
		return true;
	}

	/**
	 * Is one node parallel to another.
	 * 
	 * @return true iff parallel
	 */
	public static boolean isParallel(BoostedNode node, BoostedNode node2) {
		boolean nodeBefore2 = isBefore(node, node2);
		boolean node2BeforeNode = isBefore(node2, node);
		return !nodeBefore2 && !node2BeforeNode;
	}

	/**
	 * Is one node before another (a predecessor of a predecessor)
	 * 
	 * @param node
	 *            is this node before node2
	 * @return true iff before
	 */
	public static boolean isBefore(BoostedNode node, BoostedNode node2) {
		if (node == node2 || node.equals(node2)){
			return false;
		} else {
			Set nodesAfter = new HashSet();
			fillAllNodesAfterIncluding(node, nodesAfter);
			boolean result = nodesAfter.contains(node2);
			return result;
		}
	}

	/**
	 * Puts a node and its successors into a set
	 * 
	 * @param nodeToInspect
	 *            the node
	 * @param nodesAfter
	 *            the set
	 */
	public static void fillAllNodesAfterIncluding(BoostedNode nodeToInspect, Set nodesAfter) {
		if (nodesAfter.contains(nodeToInspect)) {
			return; // nothing more to do
		} else {
			nodesAfter.add(nodeToInspect);
			for (BoostedNode node : getSuccessors(nodeToInspect)) {
				fillAllNodesAfterIncluding(node, nodesAfter);
			}
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy