diff --git a/acropolis-report/src/main/kotlin/org/ephyra/acropolis/report/api/model/Graph.kt b/acropolis-report/src/main/kotlin/org/ephyra/acropolis/report/api/model/Graph.kt index 704567d..fc0e096 100644 --- a/acropolis-report/src/main/kotlin/org/ephyra/acropolis/report/api/model/Graph.kt +++ b/acropolis-report/src/main/kotlin/org/ephyra/acropolis/report/api/model/Graph.kt @@ -30,6 +30,34 @@ class Graph { fun findNode(label: String): Node? { return nodes.find { node -> node.label == label } } + + // Only valid for di-graphs, otherwise much allow edges if incoming edges have a corresponding outgoing edge. + fun findSourceNodes(): HashSet { + val tempNodes = HashSet() + tempNodes.addAll(nodes) + + edges.forEach { edge -> + val node = edge.sink + tempNodes.remove(node) + } + + return tempNodes + } + + fun firstNode(): Node { + return nodes.first() + } + + fun findNodesConnectedFrom(node: Node): HashSet { + val tempNodes = HashSet() + edges.forEach { edge -> + if (edge.source == node) { + tempNodes.add(edge.sink) + } + } + + return tempNodes + } } class Node( diff --git a/acropolis-report/src/main/kotlin/org/ephyra/acropolis/report/impl/ReportRunner.kt b/acropolis-report/src/main/kotlin/org/ephyra/acropolis/report/impl/ReportRunner.kt index 78eafd3..1e62973 100644 --- a/acropolis-report/src/main/kotlin/org/ephyra/acropolis/report/impl/ReportRunner.kt +++ b/acropolis-report/src/main/kotlin/org/ephyra/acropolis/report/impl/ReportRunner.kt @@ -1,12 +1,55 @@ package org.ephyra.acropolis.report.impl import org.ephyra.acropolis.report.api.IReportRunner +import org.ephyra.acropolis.report.api.model.Graph import org.ephyra.acropolis.report.api.model.GraphContainer +import org.ephyra.acropolis.report.api.model.Node import org.springframework.stereotype.Component @Component private class ReportRunner : IReportRunner { override fun run(graphContainer: GraphContainer) { println("Running report") + buildNodeDepth(graphContainer.graph) + + + } + + fun buildNodeDepth(graph: Graph): HashMap { + val startNode = pickStartNode(graph) + + val depths = HashMap() + depths[startNode] = 0 + + nodeDepth(startNode, graph, depths, 1) + + return depths + } + + fun nodeDepth(currentNode: Node, graph: Graph, depths: HashMap, depth: Int) { + val connected = graph.findNodesConnectedFrom(currentNode) + + // Remove all the nodes which are already numbered. + connected.removeAll(depths.keys) + + // Number each of the connected nodes. + connected.forEach { con -> + depths[con] = depth + } + + // Now apply the same process to each of the nodes we just numbered. + connected.forEach { con -> + nodeDepth(con, graph, depths, depth + 1) + } + } + + fun pickStartNode(graph: Graph): Node { + val sourceNodes = graph.findSourceNodes() + return if (sourceNodes.isEmpty()) { + graph.firstNode() + } + else { + sourceNodes.first() + } } }