in xbean-reflect/src/main/java/org/apache/xbean/recipe/ObjectGraph.java [110:165]
private LinkedHashMap<String, Recipe> getSortedRecipes(List<String> names) {
// construct the graph
Map<String, Node> nodes = new LinkedHashMap<String, Node>();
for (String name : names) {
Object object = repository.get(name);
if (object instanceof Recipe) {
Recipe recipe = (Recipe) object;
if (!recipe.getName().equals(name)) {
throw new ConstructionException("Recipe '" + name + "' returned from the repository has name '" + name + "'");
}
createNode(name, recipe, nodes);
}
}
// find all initial leaf nodes (and islands)
List<Node> sortedNodes = new ArrayList<Node>(nodes.size());
LinkedList<Node> leafNodes = new LinkedList<Node>();
for (Node n : nodes.values()) {
if (n.referenceCount == 0) {
// if the node is totally isolated (no in or out refs),
// move it directly to the finished list, so they are first
if (n.references.size() == 0) {
sortedNodes.add(n);
} else {
leafNodes.add(n);
}
}
}
// pluck the leaves until there are no leaves remaining
while (!leafNodes.isEmpty()) {
Node node = leafNodes.removeFirst();
sortedNodes.add(node);
for (Node ref : node.references) {
ref.referenceCount--;
if (ref.referenceCount == 0) {
leafNodes.add(ref);
}
}
}
// There are no more leaves so if there are there still
// unprocessed nodes in the graph, we have one or more curcuits
if (sortedNodes.size() != nodes.size()) {
findCircuit(nodes.values().iterator().next(), new ArrayList<Recipe>(nodes.size()));
// find circuit should never fail, if it does there is a programming error
throw new ConstructionException("Internal Error: expected a CircularDependencyException");
}
// return the recipes
LinkedHashMap<String, Recipe> sortedRecipes = new LinkedHashMap<String, Recipe>();
for (Node node : sortedNodes) {
sortedRecipes.put(node.name, node.recipe);
}
return sortedRecipes;
}