| /* |
| * Copyright 2012-present Facebook, Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may |
| * not use this file except in compliance with the License. You may obtain |
| * a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package com.facebook.buck.rules; |
| |
| import com.google.common.base.Preconditions; |
| import com.google.common.collect.ImmutableList; |
| |
| import java.util.Comparator; |
| |
| /** |
| * A utility to create a {@link Comparator} based on a list such that when the elements are |
| * compared, the original list order is preserved. |
| */ |
| final class RetainOrderComparator { |
| |
| /** Utility class: do not instantiate. */ |
| private RetainOrderComparator() {} |
| |
| /** |
| * This is meant to be used for testing when a list of objects created via EasyMock need to be |
| * added to a SortedSet: |
| * <pre> |
| * Iterable<T> iterable; |
| * Comparator<T> comparator = RetainOrderComparator.createComparator(iterable); |
| * ImmutableSortedSet<T> sortedElements = ImmutableSortedSet.copyOf(comparator, iterable); |
| * </pre> |
| */ |
| public static <T> Comparator<T> createComparator(Iterable<T> iterable) { |
| final ImmutableList<T> items = ImmutableList.copyOf(iterable); |
| return new Comparator<T>() { |
| |
| @Override |
| public int compare(T a, T b) { |
| int indexA = -1; |
| int indexB = -1; |
| int index = 0; |
| for (T item : items) { |
| // Note that == is used rather than .equals() because this is often used with a list of |
| // objects created via EasyMock, which means it would be a pain to mock out all of the |
| // calls to .equals(). Fortunately, most lists used during are short, so this is not |
| // prohibitively expensive even though it is O(N). |
| if (a == item) { |
| indexA = index; |
| } |
| if (b == item) { |
| indexB = index; |
| } |
| ++index; |
| } |
| |
| Preconditions.checkState(indexA >= 0, "The first element must be in the collection"); |
| Preconditions.checkState(indexB >= 0, "The second element must be in the collection"); |
| |
| return indexA - indexB; |
| } |
| }; |
| } |
| } |