001    package org.junit.runner.manipulation;
002    
003    import java.util.Collection;
004    import java.util.Collections;
005    import java.util.HashSet;
006    import java.util.List;
007    import java.util.Set;
008    
009    import org.junit.runner.Description;
010    
011    /**
012     * Orders tests.
013     *
014     * @since 4.13
015     */
016    public final class Orderer  {
017        private final Ordering ordering;
018    
019        Orderer(Ordering delegate) {
020            this.ordering = delegate;
021        }
022    
023        /**
024         * Orders the descriptions.
025         *
026         * @return descriptions in order
027         */
028        public List<Description> order(Collection<Description> descriptions)
029                throws InvalidOrderingException {
030            List<Description> inOrder = ordering.orderItems(
031                    Collections.unmodifiableCollection(descriptions));
032            if (!ordering.validateOrderingIsCorrect()) {
033                return inOrder;
034            }
035    
036            Set<Description> uniqueDescriptions = new HashSet<Description>(descriptions);
037            if (!uniqueDescriptions.containsAll(inOrder)) {
038                throw new InvalidOrderingException("Ordering added items");
039            }
040            Set<Description> resultAsSet = new HashSet<Description>(inOrder);
041            if (resultAsSet.size() != inOrder.size()) {
042                throw new InvalidOrderingException("Ordering duplicated items");
043            } else if (!resultAsSet.containsAll(uniqueDescriptions)) {
044                throw new InvalidOrderingException("Ordering removed items");
045            }
046    
047            return inOrder;
048        }
049    
050        /**
051         * Order the tests in <code>target</code>.
052         *
053         * @throws InvalidOrderingException if ordering does something invalid (like remove or add
054         * children)
055         */
056        public void apply(Object target) throws InvalidOrderingException {
057            if (target instanceof Orderable) {
058                Orderable orderable = (Orderable) target;
059                orderable.order(this);
060            }
061        }
062    }