001: /*
002: * Copyright 2006-2007, Unitils.org
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.unitils.reflectionassert;
017:
018: import org.apache.commons.lang.ArrayUtils;
019:
020: import java.util.*;
021:
022: /**
023: * todo javadoc
024: *
025: * @author Tim Ducheyne
026: * @author Filip Neven
027: */
028: public class CollectionComparator extends ReflectionComparator {
029:
030: // todo javadoc
031: public CollectionComparator(ReflectionComparator chainedComparator) {
032: super (chainedComparator);
033: }
034:
035: // todo javadoc
036: public boolean canHandle(Object left, Object right) {
037: return (left != null && right != null)
038: && (left.getClass().isArray() || left instanceof Collection)
039: && (right.getClass().isArray() || right instanceof Collection);
040: }
041:
042: // todo javadoc
043: @Override
044: protected Difference doGetDifference(Object left, Object right,
045: Stack<String> fieldStack,
046: Map<TraversedInstancePair, Boolean> traversedInstancePairs) {
047: // Convert to list and compare as collection
048: Collection<?> leftCollection = convertToCollection(left);
049: Collection<?> rightCollection = convertToCollection(right);
050:
051: if (leftCollection.size() != rightCollection.size()) {
052: return new Difference(
053: "Different array/collection sizes. Left size: "
054: + leftCollection.size() + ", right size: "
055: + rightCollection.size(), left, right,
056: fieldStack);
057: }
058:
059: int i = 0;
060: Iterator<?> lhsIterator = leftCollection.iterator();
061: Iterator<?> rhsIterator = rightCollection.iterator();
062: while (lhsIterator.hasNext() && rhsIterator.hasNext()) {
063: fieldStack.push("" + i++);
064: Difference difference = rootComparator.getDifference(
065: lhsIterator.next(), rhsIterator.next(), fieldStack,
066: traversedInstancePairs);
067: if (difference != null) {
068: return difference;
069: }
070: fieldStack.pop();
071: }
072: return null;
073: }
074:
075: /**
076: * Converts the given array or collection object (possibly primitive array) to type Collection
077: *
078: * @param object the array or collection
079: * @return the object collection
080: */
081: protected Collection<?> convertToCollection(Object object) {
082: if (object instanceof Collection<?>) {
083: return (Collection<?>) object;
084: }
085:
086: // If needed convert primitive array to object array
087: Object[] objectArray = convertToObjectArray(object);
088:
089: // Convert array to collection
090: return Arrays.asList(objectArray);
091: }
092:
093: /**
094: * Converts the given array object (possibly primitive array) to type Object[]
095: *
096: * @param object the array
097: * @return the object array
098: */
099: protected Object[] convertToObjectArray(Object object) {
100: if (object instanceof byte[]) {
101: return ArrayUtils.toObject((byte[]) object);
102:
103: } else if (object instanceof short[]) {
104: return ArrayUtils.toObject((short[]) object);
105:
106: } else if (object instanceof int[]) {
107: return ArrayUtils.toObject((int[]) object);
108:
109: } else if (object instanceof long[]) {
110: return ArrayUtils.toObject((long[]) object);
111:
112: } else if (object instanceof char[]) {
113: return ArrayUtils.toObject((char[]) object);
114:
115: } else if (object instanceof float[]) {
116: return ArrayUtils.toObject((float[]) object);
117:
118: } else if (object instanceof double[]) {
119: return ArrayUtils.toObject((double[]) object);
120:
121: } else if (object instanceof boolean[]) {
122: return ArrayUtils.toObject((boolean[]) object);
123:
124: } else {
125: return (Object[]) object;
126: }
127: }
128: }
|