/* * Copyright 2008, Unitils.org * * 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 org.unitils.reflectionassert.comparator.impl; import org.unitils.reflectionassert.ReflectionComparator; import org.unitils.reflectionassert.comparator.Comparator; import org.unitils.reflectionassert.difference.CollectionDifference; import org.unitils.reflectionassert.difference.Difference; import static org.unitils.util.CollectionUtils.convertToCollection; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; /** * 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. * * @author Tim Ducheyne * @author Filip Neven */ public class CollectionComparator 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 */ public Difference compare(Object left, Object right, boolean onlyFirstDifference, ReflectionComparator reflectionComparator) { // Convert to list and compare as collection List<Object> leftList = new ArrayList<Object>(convertToCollection(left)); List<Object> rightList = new ArrayList<Object>(convertToCollection(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++; Difference elementDifference = reflectionComparator.getDifference(leftIterator.next(), rightIterator.next(), 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; } }