/* * Copyright 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file 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 com.amazonaws.services.dynamodbv2.testing; import com.amazonaws.services.dynamodbv2.model.AttributeValue; import java.util.Collection; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; public class AttrMatcher extends BaseMatcher> { private final Map expected; private final boolean invert; public static AttrMatcher invert(Map expected) { return new AttrMatcher(expected, true); } public static AttrMatcher match(Map expected) { return new AttrMatcher(expected, false); } public AttrMatcher(Map expected, boolean invert) { this.expected = expected; this.invert = invert; } @Override public boolean matches(Object item) { @SuppressWarnings("unchecked") Map actual = (Map) item; if (!expected.keySet().equals(actual.keySet())) { return invert; } for (String key : expected.keySet()) { AttributeValue e = expected.get(key); AttributeValue a = actual.get(key); if (!attrEquals(a, e)) { return invert; } } return !invert; } public static boolean attrEquals(AttributeValue e, AttributeValue a) { if (!isEqual(e.getB(), a.getB()) || !isEqual(e.getBOOL(), a.getBOOL()) || !isSetEqual(e.getBS(), a.getBS()) || !isEqual(e.getN(), a.getN()) || !isSetEqual(e.getNS(), a.getNS()) || !isEqual(e.getNULL(), a.getNULL()) || !isEqual(e.getS(), a.getS()) || !isSetEqual(e.getSS(), a.getSS())) { return false; } // Recursive types need special handling if (e.getM() == null ^ a.getM() == null) { return false; } else if (e.getM() != null) { if (!e.getM().keySet().equals(a.getM().keySet())) { return false; } for (final String key : e.getM().keySet()) { if (!attrEquals(e.getM().get(key), a.getM().get(key))) { return false; } } } if (e.getL() == null ^ a.getL() == null) { return false; } else if (e.getL() != null) { if (e.getL().size() != a.getL().size()) { return false; } for (int x = 0; x < e.getL().size(); x++) { if (!attrEquals(e.getL().get(x), a.getL().get(x))) { return false; } } } return true; } @Override public void describeTo(Description description) {} private static boolean isEqual(Object o1, Object o2) { if (o1 == null ^ o2 == null) { return false; } if (o1 == o2) return true; return o1.equals(o2); } private static boolean isSetEqual(Collection c1, Collection c2) { if (c1 == null ^ c2 == null) { return false; } if (c1 != null) { Set s1 = new HashSet(c1); Set s2 = new HashSet(c2); if (!s1.equals(s2)) { return false; } } return true; } }