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 static org.unitils.reflectionassert.ReflectionComparatorChainFactory.STRICT_COMPARATOR;
019:
020: import java.util.HashMap;
021: import java.util.Iterator;
022: import java.util.Map;
023: import java.util.Stack;
024:
025: /**
026: * todo javadoc
027: *
028: * @author Filip Neven
029: * @author Tim Ducheyne
030: */
031: public class MapComparator extends ReflectionComparator {
032:
033: // todo javadoc
034: public MapComparator(ReflectionComparator chainedComparator) {
035: super (chainedComparator);
036: }
037:
038: // todo javadoc
039: public boolean canHandle(Object left, Object right) {
040: return (left != null && right != null)
041: && (left instanceof Map && right instanceof Map);
042: }
043:
044: // todo javadoc
045: @Override
046: protected Difference doGetDifference(Object left, Object right,
047: Stack<String> fieldStack,
048: Map<TraversedInstancePair, Boolean> traversedInstancePairs) {
049: Map<?, ?> leftMap = (Map<?, ?>) left;
050: Map<?, ?> rightMap = (Map<?, ?>) right;
051:
052: if (leftMap.size() != rightMap.size()) {
053: return new Difference("Different map sizes.", left, right,
054: fieldStack);
055: }
056:
057: // Create copy from which we can remove elements.
058: Map<Object, Object> rightCopy = new HashMap<Object, Object>(
059: rightMap);
060:
061: for (Map.Entry<?, ?> lhsEntry : leftMap.entrySet()) {
062: Object lhsKey = lhsEntry.getKey();
063: Object lhsValue = lhsEntry.getValue();
064: fieldStack.push("" + lhsKey);
065:
066: boolean found = false;
067: Iterator<Map.Entry<Object, Object>> rhsIterator = rightCopy
068: .entrySet().iterator();
069: while (rhsIterator.hasNext()) {
070: Map.Entry<Object, Object> rhsEntry = rhsIterator.next();
071: Object rhsKey = rhsEntry.getKey();
072: Object rhsValue = rhsEntry.getValue();
073:
074: // compare keys using strict reflection compare
075: boolean isKeyEqual = STRICT_COMPARATOR.isEqual(lhsKey,
076: rhsKey);
077: if (isKeyEqual) {
078: found = true;
079: rhsIterator.remove();
080:
081: // compare values
082: Difference difference = rootComparator
083: .getDifference(lhsValue, rhsValue,
084: fieldStack, traversedInstancePairs);
085: if (difference != null) {
086: return difference;
087: }
088: break;
089: }
090: }
091: fieldStack.pop();
092:
093: if (!found) {
094: return new Difference(
095: "Left key not found in right map. Left key: "
096: + lhsEntry.getKey(), left, right,
097: fieldStack);
098: }
099: }
100: return null;
101: }
102: }
|