diff --git a/common/src/main/java/org/keycloak/common/util/MultivaluedHashMap.java b/common/src/main/java/org/keycloak/common/util/MultivaluedHashMap.java index f0b3f08633..2e3f4d3e50 100755 --- a/common/src/main/java/org/keycloak/common/util/MultivaluedHashMap.java +++ b/common/src/main/java/org/keycloak/common/util/MultivaluedHashMap.java @@ -47,7 +47,7 @@ public class MultivaluedHashMap extends HashMap> public void putSingle(K key, V value) { - List list = new ArrayList(); + List list = new ArrayList<>(); list.add(value); put(key, list); } @@ -101,11 +101,11 @@ public class MultivaluedHashMap extends HashMap> { List list = get(key); if (list == null) - put(key, list = new ArrayList()); + put(key, list = new ArrayList<>()); return list; } - public void addAll(MultivaluedHashMap other) + public final void addAll(MultivaluedHashMap other) { for (Map.Entry> entry : other.entrySet()) { @@ -121,15 +121,11 @@ public class MultivaluedHashMap extends HashMap> return false; } for (Map.Entry> e : entrySet()) { - List olist = omap.get(e.getKey()); - if (e.getValue().size() != olist.size()) { - return false; - } - for (V v : e.getValue()) { - if (!olist.contains(v)) { - return false; - } - } + List list = e.getValue(); + List olist = omap.get(e.getKey()); + if (!(list.size() == olist.size() && list.containsAll(olist) && olist.containsAll(list))) { + return false; + } } return true; } diff --git a/common/src/test/java/org/keycloak/common/util/MultivaluedHashMapTest.java b/common/src/test/java/org/keycloak/common/util/MultivaluedHashMapTest.java new file mode 100644 index 0000000000..99dc3fcd67 --- /dev/null +++ b/common/src/test/java/org/keycloak/common/util/MultivaluedHashMapTest.java @@ -0,0 +1,142 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * 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.keycloak.common.util; + +import java.util.Arrays; +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * + * @author tkyjovsk + */ +public class MultivaluedHashMapTest { + + public void equalsIgnoreValueOrder_shouldReturnTrueForEqualMaps(MultivaluedHashMap map, MultivaluedHashMap equalMap) { + assertTrue(String.format("MultivaluedHashMap.equalsIgnoreValueOrder() should return `true` for the same object. \nmap: %s", map), + map.equalsIgnoreValueOrder(map)); + assertTrue(String.format("MultivaluedHashMap.equalsIgnoreValueOrder() should return `true` for maps that are equal. \nmap1: %s \nmap2: %s", map, equalMap), + map.equalsIgnoreValueOrder(equalMap)); + assertTrue(String.format("MultivaluedHashMap.equalsIgnoreValueOrder() should return `true` for maps that are equal. \nmap1: %s \nmap2: %s", equalMap, map), + equalMap.equalsIgnoreValueOrder(map)); + } + + public void equalsIgnoreValueOrder_shouldReturnFalseForDifferentMaps(MultivaluedHashMap map, MultivaluedHashMap differentMap) { + assertFalse(String.format("MultivaluedHashMap.equalsIgnoreValueOrder() should return `false` for maps that are different. \nmap1: %s \nmap2: %s", map, differentMap), + map.equalsIgnoreValueOrder(differentMap)); + assertFalse(String.format("MultivaluedHashMap.equalsIgnoreValueOrder() should return `false` for maps that are different. \nmap1: %s \nmap2: %s", differentMap, map), + differentMap.equalsIgnoreValueOrder(map)); + } + + @Test + public void testEqualsIgnoreValueOrder_exactlyEqual() { + MultivaluedHashMap map = new MultivaluedHashMap<>(); + MultivaluedHashMap equalMap = new MultivaluedHashMap<>(); + map.put(1, Arrays.asList(1, 2, 3)); + equalMap.put(1, Arrays.asList(1, 2, 3)); + equalsIgnoreValueOrder_shouldReturnTrueForEqualMaps(map, equalMap); + + map.put(2, Arrays.asList(4, 5, 6)); + equalMap.put(2, Arrays.asList(4, 5, 6)); + equalsIgnoreValueOrder_shouldReturnTrueForEqualMaps(map, equalMap); + + map.put(3, Arrays.asList(7, 8, 9)); + equalMap.put(3, Arrays.asList(7, 8, 9)); + equalsIgnoreValueOrder_shouldReturnTrueForEqualMaps(map, equalMap); + } + + @Test + public void testEqualsIgnoreValueOrder_sameLengthSameValues() { + MultivaluedHashMap map = new MultivaluedHashMap<>(); + MultivaluedHashMap equalMap = new MultivaluedHashMap<>(); + map.put(1, Arrays.asList(1, 2, 3)); + equalMap.put(1, Arrays.asList(3, 2, 1)); + equalsIgnoreValueOrder_shouldReturnTrueForEqualMaps(map, equalMap); + + map.put(2, Arrays.asList(4, 5, 6)); + equalMap.put(2, Arrays.asList(5, 6, 4)); + equalsIgnoreValueOrder_shouldReturnTrueForEqualMaps(map, equalMap); + + map.put(3, Arrays.asList(7, 8, 9)); + equalMap.put(3, Arrays.asList(9, 7, 8)); + equalsIgnoreValueOrder_shouldReturnTrueForEqualMaps(map, equalMap); + + map.clear(); + equalMap.clear(); + map.put(1, Arrays.asList(1, 2, 3, 4, 5)); + map.put(2, Arrays.asList(4, 5, 6, 7, 8)); + equalMap.put(1, Arrays.asList(4, 3, 2, 5, 1)); + equalMap.put(2, Arrays.asList(6, 7, 4, 8, 5)); + equalsIgnoreValueOrder_shouldReturnTrueForEqualMaps(map, equalMap); + } + + @Test + public void testEqualsIgnoreValueOrder_sameLengthDifferentValues() { + MultivaluedHashMap map = new MultivaluedHashMap<>(); + MultivaluedHashMap differentMap = new MultivaluedHashMap<>(); + map.put(1, Arrays.asList(1, 2, 3)); + differentMap.put(1, Arrays.asList(1, 2, 2)); + equalsIgnoreValueOrder_shouldReturnFalseForDifferentMaps(map, differentMap); + + map.clear(); + differentMap.clear(); + map.put(1, Arrays.asList(1, 2, 3)); + map.put(2, Arrays.asList(4, 5, 6)); + differentMap.put(1, Arrays.asList(1, 2, 3)); + differentMap.put(2, Arrays.asList(4, 5, 5)); + equalsIgnoreValueOrder_shouldReturnFalseForDifferentMaps(map, differentMap); + } + + @Test + public void testEqualsIgnoreValueOrder_differentLengthSameValues() { + MultivaluedHashMap map = new MultivaluedHashMap<>(); + MultivaluedHashMap differentMap = new MultivaluedHashMap<>(); + map.put(1, Arrays.asList(1, 2, 3)); + differentMap.put(1, Arrays.asList(1, 2, 2, 3)); + equalsIgnoreValueOrder_shouldReturnFalseForDifferentMaps(map, differentMap); + + map.clear(); + differentMap.clear(); + map.put(1, Arrays.asList(1, 2, 3)); + map.put(2, Arrays.asList(4, 5, 6)); + differentMap.put(1, Arrays.asList(1, 2, 3)); + differentMap.put(2, Arrays.asList(4, 5, 5, 4, 6)); + equalsIgnoreValueOrder_shouldReturnFalseForDifferentMaps(map, differentMap); + } + + @Test + public void testEqualsIgnoreValueOrder_differentLengthDifferentValues() { + MultivaluedHashMap map = new MultivaluedHashMap<>(); + MultivaluedHashMap differentMap = new MultivaluedHashMap<>(); + map.put(1, Arrays.asList(1, 2, 3)); + differentMap.put(1, Arrays.asList(1, 2, 3, 4)); + equalsIgnoreValueOrder_shouldReturnFalseForDifferentMaps(map, differentMap); + + map.clear(); + differentMap.clear(); + map.put(1, Arrays.asList(1, 2, 3)); + map.put(2, Arrays.asList(4, 5, 6)); + differentMap.put(1, Arrays.asList(1, 2, 3)); + equalsIgnoreValueOrder_shouldReturnFalseForDifferentMaps(map, differentMap); // diff entrySet size + + differentMap.put(2, Arrays.asList(4, 5, 6, 7)); + equalsIgnoreValueOrder_shouldReturnFalseForDifferentMaps(map, differentMap); + } + +}