private LinkedHashMap getSortedRecipes()

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;
    }