@NotNull public static <T> LinkedHashSet<T> newLinkedHashSet(@NotNull Iterable<? extends T> elements) { if (elements instanceof Collection) { @SuppressWarnings("unchecked") Collection<? extends T> collection = (Collection<? extends T>) elements; return new com.intellij.util.containers.LinkedHashSet<T>(collection); } return copy(ContainerUtilRt.<T>newLinkedHashSet(), elements); }
/** * Arranges (re-orders) given entries according to the given rules. * * @param entries entries to arrange * @param rules rules to use for arrangement * @param rulesByPriority rules sorted by priority ('public static' rule will have higher priority * than 'public') * @param <E> arrangement entry type * @return arranged list of the given rules */ @SuppressWarnings("AssignmentToForLoopParameter") @NotNull public static <E extends ArrangementEntry> List<E> arrange( @NotNull Collection<E> entries, @NotNull List<? extends ArrangementMatchRule> rules, @NotNull List<? extends ArrangementMatchRule> rulesByPriority) { List<E> arranged = ContainerUtilRt.newArrayList(); Set<E> unprocessed = ContainerUtilRt.newLinkedHashSet(); List<Pair<Set<ArrangementEntry>, E>> dependent = ContainerUtilRt.newArrayList(); for (E entry : entries) { List<? extends ArrangementEntry> dependencies = entry.getDependencies(); if (dependencies == null) { unprocessed.add(entry); } else { if (dependencies.size() == 1 && dependencies.get(0) == entry.getParent()) { // Handle a situation when the entry is configured to be at the first parent's children. arranged.add(entry); } else { Set<ArrangementEntry> first = new HashSet<ArrangementEntry>(dependencies); dependent.add(Pair.create(first, entry)); } } } Set<E> matched = new HashSet<E>(); MultiMap<ArrangementMatchRule, E> elementsByRule = new MultiMap<ArrangementMatchRule, E>(); for (ArrangementMatchRule rule : rulesByPriority) { matched.clear(); for (E entry : unprocessed) { if (entry.canBeMatched() && rule.getMatcher().isMatched(entry)) { elementsByRule.putValue(rule, entry); matched.add(entry); } } unprocessed.removeAll(matched); } for (ArrangementMatchRule rule : rules) { if (elementsByRule.containsKey(rule)) { final Collection<E> arrangedEntries = elementsByRule.get(rule); // Sort by name if necessary. if (StdArrangementTokens.Order.BY_NAME.equals(rule.getOrderType())) { sortByName((List<E>) arrangedEntries); } arranged.addAll(arrangedEntries); } } arranged.addAll(unprocessed); for (int i = 0; i < arranged.size() && !dependent.isEmpty(); i++) { E e = arranged.get(i); for (Iterator<Pair<Set<ArrangementEntry>, E>> iterator = dependent.iterator(); iterator.hasNext(); ) { Pair<Set<ArrangementEntry>, E> pair = iterator.next(); pair.first.remove(e); if (pair.first.isEmpty()) { iterator.remove(); arranged.add(i + 1, pair.second); } } } return arranged; }