/** * Topological sorts the graph using and returns the order as list. It tries to bring Objects on * one common level in a sorted order. If a loop is detected, it returns null as no sorting is * possible. * * @return DOCUMENT ME! * @throws IllegalStateException DOCUMENT ME! */ public final Set<T> orderedTopologicalSort() { final Set<T> result = TypeSafeCollections.newLinkedHashSet(); final Map<T, Set<T>> orderedAdjacencyListCopy = TypeSafeCollections.newLinkedHashMap(); final List<T> pathsToOrderList = TypeSafeCollections.newArrayList(adjacencyList.keySet()); if (comparator != null) { Collections.sort(pathsToOrderList, comparator); } for (final T item : pathsToOrderList) { orderedAdjacencyListCopy.put(item, new HashSet<T>(adjacencyList.get(item))); } while (!orderedAdjacencyListCopy.isEmpty()) { final List<T> current = TypeSafeCollections.newArrayList(); final Iterator<Entry<T, Set<T>>> it = orderedAdjacencyListCopy.entrySet().iterator(); T item = null; while (it.hasNext()) { final Entry<T, Set<T>> entry = it.next(); item = entry.getKey(); final Set<T> chk = entry.getValue(); if ((chk == null) || chk.isEmpty()) { it.remove(); current.add(item); for (final Set<T> set : orderedAdjacencyListCopy.values()) { set.remove(item); } } } if (current.isEmpty()) { throw new IllegalStateException( "Relationgraph has cyclic dependencies on item " + item + "!"); } result.addAll(current); } return result; }
/** * DOCUMENT ME! * * @return DOCUMENT ME! */ public final Set<T> reverseOrderedTopologicalSort() { final List<T> tmp = TypeSafeCollections.newArrayList(orderedTopologicalSort()); Collections.reverse(tmp); final Set<T> res = TypeSafeCollections.newLinkedHashSet(tmp); return res; }