public static List sort()

in src/main/java/org/apache/openejb/tools/release/util/References.java [33:111]


    public static <T> List<T> sort(final List<T> objects, final Visitor<T> visitor) {

        if (objects.size() <= 1) {
            return objects;
        }

        final Map<String, Node> nodes = new LinkedHashMap<String, Node>();

        // Create nodes
        for (final T obj : objects) {
            final String name = visitor.getName(obj);
            final Node node = new Node(name, obj);
            nodes.put(name, node);
        }

        // Link nodes
        for (final Node node : nodes.values()) {
            for (final String name : visitor.getReferences((T) node.object)) {
                final Node ref = nodes.get(name);
                if (ref == null) throw new IllegalArgumentException("No such object in list: " + name);
                node.references.add(ref);
                node.initialReferences.add(ref);
            }
        }
        boolean circuitFounded = false;
        for (final Node node : nodes.values()) {
            final Set<Node> visitedNodes = new HashSet<Node>();
            if (!normalizeNodeReferences(node, node, visitedNodes)) {
                circuitFounded = true;
                break;
            }
            node.references.addAll(visitedNodes);
        }

        //detect circus
        if (circuitFounded) {
            final Set<Circuit> circuits = new LinkedHashSet<Circuit>();

            for (final Node node : nodes.values()) {
                findCircuits(circuits, node, new java.util.Stack<Node>());
            }

            final ArrayList<Circuit> list = new ArrayList<Circuit>(circuits);
            Collections.sort(list);

            final List<List> all = new ArrayList<List>();
            for (final Circuit circuit : list) {
                all.add(unwrap(circuit.nodes));
            }

            throw new CircularReferencesException(all);
        }

        //Build Double Link Node List
        final Node rootNode = new Node(null, null);
        rootNode.previous = rootNode;
        rootNode.next = nodes.values().iterator().next();

        for (final Node node : nodes.values()) {
            node.previous = rootNode.previous;
            rootNode.previous.next = node;
            node.next = rootNode;
            rootNode.previous = node;
        }

        for (final Node node : nodes.values()) {
            for (final Node reference : node.references) {
                swap(node, reference, rootNode);
            }
        }

        final List sortedList = new ArrayList(nodes.size());
        Node currentNode = rootNode.next;
        while (currentNode != rootNode) {
            sortedList.add(currentNode.object);
            currentNode = currentNode.next;
        }
        return sortedList;
    }