package org.test4j.hamcrest.matcher.property.comparator; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.test4j.hamcrest.matcher.property.difference.CollectionDifference; import org.test4j.hamcrest.matcher.property.difference.Difference; import org.test4j.hamcrest.matcher.property.reflection.ReflectionComparator; import org.test4j.tools.commons.ListHelper; /** * Comparator for collections and arrays. All elements are compared in the same * order, i.e. element 1 of the left collection with element 1 of the right * collection and so on. */ public class ListComparator implements Comparator { /** * Returns true when both objects are arrays or collections. * * @param left * The left object * @param right * The right object * @return True in case of arrays/collections */ public boolean canCompare(Object left, Object right) { if (left == null || right == null) { return false; } if ((left.getClass().isArray() || left instanceof Collection) && (right.getClass().isArray() || right instanceof Collection)) { return true; } return false; } /** * Compared the given collections/arrays. * * @param left * The left collection/array, not null * @param right * The right collection/array, not null * @param onlyFirstDifference * True if only the first difference should be returned * @param reflectionComparator * The root comparator for inner comparisons, not null * @return A CollectionDifference or null if both collections are equal */ @SuppressWarnings({ "rawtypes" }) public Difference compare(Object left, Object right, boolean onlyFirstDifference, ReflectionComparator reflectionComparator) { List leftList = ListHelper.toList(left); List rightList = ListHelper.toList(right); int elementIndex = -1; CollectionDifference difference = new CollectionDifference("Different elements", left, right, leftList, rightList); Iterator<?> leftIterator = leftList.iterator(); Iterator<?> rightIterator = rightList.iterator(); while (leftIterator.hasNext() && rightIterator.hasNext()) { elementIndex++; Object leftItem = leftIterator.next(); Object rightItem = rightIterator.next(); Difference elementDifference = reflectionComparator.getDifference(leftItem, rightItem, onlyFirstDifference); if (elementDifference != null) { difference.addElementDifference(elementIndex, elementDifference); if (onlyFirstDifference) { return difference; } } } // check for missing elements int leftElementIndex = elementIndex; while (leftIterator.hasNext()) { leftIterator.next(); difference.addLeftMissingIndex(++leftElementIndex); } int rightElementIndex = elementIndex; while (rightIterator.hasNext()) { rightIterator.next(); difference.addRightMissingIndex(++rightElementIndex); } if (difference.getElementDifferences().isEmpty() && difference.getLeftMissingIndexes().isEmpty() && difference.getRightMissingIndexes().isEmpty()) { return null; } return difference; } }