ConfigUtils { public static <K, V> Map<K, V> updateMap(final Map<K, V> original, MapDifference<K, V> diff) throws MergeException { Map<K, V> result = new HashMap<K, V>(original); if (diff.areEqual()) { return result; } for (Entry<K, V> entry : diff.entriesOnlyOnLeft().entrySet()) { V originalValue = original.get(entry.getKey()); if (ObjectUtils.equals(originalValue, entry.getValue())) { result.remove(entry.getKey()); } } for (Entry<K, V> entry : diff.entriesOnlyOnRight().entrySet()) { K key = entry.getKey(); if (original.containsKey(key)) { if (ObjectUtils.notEqual(original.get(key), entry.getValue())) { throw new MergeException(String.format( "tried to introduce a new value, but it was already there: %s (%s,%s)", key, original.get(key), entry.getValue())); } } result.put(entry.getKey(), entry.getValue()); } for (Entry<K, ValueDifference<V>> entry : diff.entriesDiffering().entrySet()) { K key = entry.getKey(); V originalValue = original.get(entry.getKey()); if (ObjectUtils.equals(originalValue, entry.getValue().leftValue())) { result.put(key, entry.getValue().rightValue()); } else if (ObjectUtils.equals(originalValue, entry.getValue().rightValue())) { result.put(key, originalValue); } else { String errorMessage = String .format( "Changes could not be applied, because original value differes from left-side of the" + "MapDifference: %s (%s,%s)", entry.getKey(), original.get(entry.getKey()), entry.getValue()); throw new MergeException(errorMessage); } } return result; } private  ConfigUtils(); static Map<K, V> updateMap(final Map<K, V> original, MapDifference<K, V> diff);  }
@Test public void testIntroduceValueAlreadySameInOriginal_shouldLeaveUnchanged() throws Exception { Map<String, String> original = ImmutableMap.of("foo", "bar", "test", "42"); Map<String, String> oldMap = ImmutableMap.of("foo", "bar"); Map<String, String> newMap = ImmutableMap.of("foo", "bar", "test", "42"); MapDifference<String, String> difference = Maps.difference(oldMap, newMap); Map<String, String> result = ConfigUtils.updateMap(original, difference); assertThat(result, is(original)); }
@Test public void testChangeValueAlreadySameInOriginal_shouldLeaveMapUnchanged() throws Exception { Map<String, String> original = ImmutableMap.of("foo", "bar", "test", "21"); Map<String, String> oldMap = ImmutableMap.of("foo", "bar", "test", "42"); Map<String, String> newMap = ImmutableMap.of("foo", "bar", "test", "21"); MapDifference<String, String> difference = Maps.difference(oldMap, newMap); Map<String, String> result = ConfigUtils.updateMap(original, difference); assertThat(result, is(original)); }
@Test public void testRemoveValueAlreadyRemovedFromOriginal_shouldLeaveOriginalUnchanged() throws Exception { Map<String, String> original = ImmutableMap.of("foo", "bar"); Map<String, String> oldMap = ImmutableMap.of("foo", "bar", "test", "21"); Map<String, String> newMap = ImmutableMap.of("foo", "bar"); MapDifference<String, String> difference = Maps.difference(oldMap, newMap); Map<String, String> result = ConfigUtils.updateMap(original, difference); assertThat(result, is(original)); }
@Test public void testRemoveValueWithOtherOriginalValue_shouldThrowException() throws Exception { Map<String, String> original = ImmutableMap.of("foo", "bar", "test", "42"); Map<String, String> oldMap = ImmutableMap.of("foo", "bar", "test", "21"); Map<String, String> newMap = ImmutableMap.of("foo", "bar"); MapDifference<String, String> difference = Maps.difference(oldMap, newMap); ConfigUtils.updateMap(original, difference); }
@Test public void testChangeKeyName_shouldChangeMap() throws Exception { Map<String, String> original = ImmutableMap.of("foo", "bar", "test", "42"); Map<String, String> oldMap = ImmutableMap.of("foo", "bar", "test", "42"); Map<String, String> newMap = ImmutableMap.of("foo", "bar", "test1", "42"); MapDifference<String, String> difference = Maps.difference(oldMap, newMap); Map<String, String> result = ConfigUtils.updateMap(original, difference); assertThat(result, is(newMap)); }
@Test public void testUpdateMulipleEntries_shouldWork() throws Exception { Map<String, String> original = ImmutableMap.of("foo", "bar", "test", "42", "other", "bleh"); Map<String, String> oldMap = ImmutableMap.of("foo", "bar", "test", "42"); Map<String, String> newMap = ImmutableMap.of("foo", "bar2", "test", "41", "x", "y"); MapDifference<String, String> difference = Maps.difference(oldMap, newMap); Map<String, String> result = ConfigUtils.updateMap(original, difference); assertThat(result, is((Map<String, String>) ImmutableMap.of("foo", "bar2", "test", "41", "x", "y", "other", "bleh"))); }
@Test public void testMakeNoChanges_shouldLeaveMapUnchanged() throws Exception { Map<String, String> original = ImmutableMap.of("foo", "bar"); Map<String, String> oldMap = ImmutableMap.copyOf(original); Map<String, String> newMap = ImmutableMap.copyOf(oldMap); MapDifference<String, String> difference = Maps.difference(oldMap, newMap); Map<String, String> result = ConfigUtils.updateMap(original, difference); assertThat(result, is(original)); }
@Test public void testIntroduceNewKey_shouldAddNewEntry() throws Exception { Map<String, String> original = ImmutableMap.of("foo", "bar"); Map<String, String> oldMap = ImmutableMap.copyOf(original); Map<String, String> newMap = ImmutableMap.of("foo", "bar", "test", "42"); MapDifference<String, String> difference = Maps.difference(oldMap, newMap); Map<String, String> result = ConfigUtils.updateMap(original, difference); assertThat(result, is(newMap)); }
@Test public void testRemoveKeyFromNewMap_shouldRemoveEntry() throws Exception { Map<String, String> original = ImmutableMap.of("foo", "bar", "test", "42"); Map<String, String> oldMap = ImmutableMap.copyOf(original); Map<String, String> newMap = ImmutableMap.of("foo", "bar"); MapDifference<String, String> difference = Maps.difference(oldMap, newMap); Map<String, String> result = ConfigUtils.updateMap(original, difference); assertThat(result, is(newMap)); }
@Test public void testValueChange_shouldChangeValue() throws Exception { Map<String, String> original = ImmutableMap.of("foo", "bar", "test", "42"); Map<String, String> oldMap = ImmutableMap.copyOf(original); Map<String, String> newMap = ImmutableMap.of("foo", "bar", "test", "21"); MapDifference<String, String> difference = Maps.difference(oldMap, newMap); Map<String, String> result = ConfigUtils.updateMap(original, difference); assertThat(result, is(newMap)); }
@Test(expected = MergeException.class) public void testChangeValueNotInOriginal_shouldThrowException() throws Exception { Map<String, String> original = ImmutableMap.of("foo", "bar"); Map<String, String> oldMap = ImmutableMap.of("foo", "bar", "test", "42"); Map<String, String> newMap = ImmutableMap.of("foo", "bar", "test", "21"); MapDifference<String, String> difference = Maps.difference(oldMap, newMap); ConfigUtils.updateMap(original, difference); }
@Test(expected = MergeException.class) public void testIntroduceValueAlreadyInOriginal_shouldThrowException() throws Exception { Map<String, String> original = ImmutableMap.of("foo", "bar", "test", "21"); Map<String, String> oldMap = ImmutableMap.of("foo", "bar"); Map<String, String> newMap = ImmutableMap.of("foo", "bar", "test", "42"); MapDifference<String, String> difference = Maps.difference(oldMap, newMap); ConfigUtils.updateMap(original, difference); }