private <S extends Node, E extends Node> E findEndNode(Node node, int depth, Class<S> startClass, Class<E> endClass)
throws GraphException {
List<Node> nextNodes = GraphUtil.getNextNodes(node);
for (Node nextNode : nextNodes) {
if (nextNode instanceof OutputNode) {
throw new GraphException("Nodes after " + startClass.getName()
+ " cannot be connected to the output without going through " + endClass.getName() + ".");
} else if (endClass.isInstance(nextNode)) {
if (depth == 0) {
// Stop the recursion here.
return (E) nextNode; // This cast is OK.
} else {
return findEndNode(nextNode, depth - 1, startClass, endClass);
}
} else if (startClass.isInstance(nextNode)) {
// handle embedded forEach
return findEndNode(nextNode, depth + 1, startClass, endClass);
} else {
return findEndNode(nextNode, depth, startClass, endClass);
}
}
throw new GraphException("Cannot find matching " + endClass.getName() + " for " + startClass.getName() + ".");
}