package org.webcat.diff; import java.util.Comparator; import java.util.List; import java.util.ListIterator; import java.util.RandomAccess; public class DiffUtils { //~ Methods ............................................................... // ---------------------------------------------------------- public static <T> boolean itemsEqual(T item1, T item2, Comparator<T> comparator) { if (item1 == null && item2 == null) { return true; } else if (item1 == null || item2 == null) { return false; } if (comparator != null) { return comparator.compare(item1, item2) == 0; } else { return item1.equals(item2); } } // ---------------------------------------------------------- public static <T> boolean listsEqual(List<T> list1, List<T> list2, Comparator<T> comparator) { if (list1.size() != list2.size()) { return false; } else { for (int i = 0; i < list1.size(); i++) { if (!itemsEqual(list1.get(i), list2.get(i), comparator)) { return false; } } } return true; } // ---------------------------------------------------------- public static <T> int listIndexOf(List<T> source, List<T> target, int start, Comparator<T> comparator) { source = source.subList(start, source.size()); int sourceSize = source.size(); int targetSize = target.size(); int maxCandidate = sourceSize - targetSize; ListIterator<T> si = source.listIterator(); nextCand: for (int candidate = 0; candidate <= maxCandidate; candidate++) { ListIterator<T> ti = target.listIterator(); for (int i=0; i < targetSize; i++) { if (!itemsEqual(ti.next(), si.next(), comparator)) { // Back up source iterator to next candidate for (int j = 0; j<i; j++) { si.previous(); } continue nextCand; } } return candidate; } return -1; // No candidate matched the target } // ---------------------------------------------------------- public static <T> int listLastIndexOf(List<T> source, List<T> target, int start, Comparator<T> comparator) { source = source.subList(0, Math.min(start + 1 + target.size(), source.size())); int sourceSize = source.size(); int targetSize = target.size(); int maxCandidate = sourceSize - targetSize; if (maxCandidate < 0) return -1; ListIterator<T> si = source.listIterator(maxCandidate); nextCand: for (int candidate = maxCandidate; candidate >= 0; candidate--) { ListIterator<T> ti = target.listIterator(); for (int i=0; i<targetSize; i++) { if (!itemsEqual(ti.next(), si.next(), comparator)) { if (candidate != 0) { // Back up source iterator to next candidate for (int j=0; j<=i+1; j++) { si.previous(); } } continue nextCand; } } return candidate; } return -1; // No candidate matched the target } // ---------------------------------------------------------- public static <T> boolean listStartsWith(List<T> list, List<T> subList, Comparator<T> comparator) { return listIndexOf(list, subList, 0, comparator) == 0; } // ---------------------------------------------------------- public static <T> boolean listEndsWith(List<T> list, List<T> subList, Comparator<T> comparator) { return listIndexOf(list, subList, 0, comparator) == list.size() - subList.size(); } }