From cdcef4649d5dc05a22c3c2c125671b6dad291632 Mon Sep 17 00:00:00 2001 From: jasc7636 Date: Mon, 15 Jun 2020 10:08:56 +0200 Subject: [PATCH 1/2] Make watcher copy method deepcopy collections --- Mage/src/main/java/mage/watchers/Watcher.java | 40 ++++-- Mage/src/test/java/mage/WatcherTest.java | 133 +++++++++++++++++- 2 files changed, 161 insertions(+), 12 deletions(-) diff --git a/Mage/src/main/java/mage/watchers/Watcher.java b/Mage/src/main/java/mage/watchers/Watcher.java index 762514ec549..14f2323a383 100644 --- a/Mage/src/main/java/mage/watchers/Watcher.java +++ b/Mage/src/main/java/mage/watchers/Watcher.java @@ -115,18 +115,38 @@ public abstract class Watcher implements Serializable { ((Set) field.get(watcher)).clear(); ((Set) field.get(watcher)).addAll((Set) field.get(this)); } else if (field.getType() == Map.class) { - Map target = ((Map) field.get(watcher)); - target.clear(); - Map source = (Map) field.get(this); - ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType(); Type valueType = parameterizedType.getActualTypeArguments()[1]; - if (valueType.getClass().getSimpleName().contains("Set")) { - source.entrySet().forEach(kv -> { - Object key = ((Map.Entry) kv).getKey(); - Set value = (Set) ((Map.Entry) kv).getValue(); - target.put(key, new HashSet<>(value)); - }); + if (valueType.getTypeName().contains("Set")) { + Map> source = (Map>) field.get(this); + Map> target = (Map>) field.get(watcher); + target.clear(); + for (Map.Entry> e : source.entrySet()) { + Set set = new HashSet<>(); + set.addAll(e.getValue()); + target.put(e.getKey(), set); + } + } + else if (valueType.getTypeName().contains("List")) { + Map> source = (Map>) field.get(this); + Map> target = (Map>) field.get(watcher); + target.clear(); + for (Map.Entry> e : source.entrySet()) { + List list = new ArrayList<>(); + list.addAll(e.getValue()); + target.put(e.getKey(), list); + } + } + else if (valueType.getTypeName().contains("Map")) { + Map> source = (Map>) field.get(this); + Map> target = (Map>) field.get(watcher); + target.clear(); + for (Map.Entry> e : source.entrySet()) { + Map map = new HashMap<>(); + map.putAll(e.getValue()); + target.put(e.getKey(), map); + } + } else { ((Map) field.get(watcher)).putAll((Map) field.get(this)); diff --git a/Mage/src/test/java/mage/WatcherTest.java b/Mage/src/test/java/mage/WatcherTest.java index 8ad06fde915..f6b3869aa1f 100644 --- a/Mage/src/test/java/mage/WatcherTest.java +++ b/Mage/src/test/java/mage/WatcherTest.java @@ -1,13 +1,17 @@ package mage; import static mage.constants.WatcherScope.GAME; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.ArrayList; +import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; import mage.constants.WatcherScope; @@ -19,7 +23,7 @@ import org.junit.Test; public class WatcherTest { @Test - public void test() { + public void testShallowCopy() { // Given Map mapField = new HashMap<>(); mapField.put("mapFieldKey1", "mapFieldValue1"); @@ -43,6 +47,104 @@ public class WatcherTest { assertEquals(ImmutableMap.of("mapFieldKey1", "mapFieldValue1", "mapFieldKey2", "mapFieldValue2"), copy.getMapField()); } + @Test + public void testDeepCopyMapOfList() { + // Given + Map> listInMapField = new HashMap<>(); + List list1 = new ArrayList<>(); + list1.add("v1"); + list1.add("v1.1"); + List list2 = new ArrayList<>(); + list2.add("v2"); + listInMapField.put("k1", list1); + listInMapField.put("k2", list2); + + TestWatcher testWatcher = new TestWatcher(GAME); + testWatcher.setListInMapField(listInMapField); + + // When + TestWatcher copy = testWatcher.copy(); + + // And + testWatcher.getListInMapField().get("k1").add("v1.2"); + List list3 = new ArrayList<>(); + list3.add("v5"); + testWatcher.getListInMapField().put("k5", list3); + + // Then + Map> copyListInMap = copy.getListInMapField(); + assertEquals(2, copyListInMap.size()); + assertTrue(copyListInMap.containsKey("k1")); + assertEquals(ImmutableList.of("v1", "v1.1"), copyListInMap.get("k1")); + assertTrue(copyListInMap.containsKey("k2")); + assertEquals(ImmutableList.of("v2"), copyListInMap.get("k2")); + } + + @Test + public void testDeepCopyMapOfSet() { + // Given + Map> setInMapField = new HashMap<>(); + Set set1 = new HashSet<>(); + set1.add("v3"); + Set set2 = new HashSet<>(); + set2.add("v4"); + set2.add("v4.1"); + setInMapField.put("k3", set1); + setInMapField.put("k4", set2); + setInMapField.put("k", new HashSet()); + + TestWatcher testWatcher = new TestWatcher(GAME); + testWatcher.setSetInMapField(setInMapField); + + // When + TestWatcher copy = testWatcher.copy(); + + // And + testWatcher.getSetInMapField().get("k3").add("v3.1"); + + // Then + Map> copySetInMap = copy.getSetInMapField(); + assertEquals(3, copySetInMap.size()); + assertTrue(copySetInMap.containsKey("k3")); + assertEquals(ImmutableSet.of("v3"), copySetInMap.get("k3")); + assertTrue(copySetInMap.containsKey("k4")); + assertEquals(ImmutableSet.of("v4", "v4.1"), copySetInMap.get("k4")); + assertTrue(copySetInMap.containsKey("k")); + assertEquals(ImmutableSet.of(), copySetInMap.get("k")); + } + + @Test + public void testDeepCopyMapOfMap() { + // Given + Map> mapInMapField = new HashMap<>(); + Map map1 = new HashMap<>(); + map1.put("k1.1", "v1.1"); + map1.put("k1.2", "v1.2"); + Map map2 = new HashMap<>(); + map2.put("k2.1", "v2.1"); + mapInMapField.put("k1", map1); + mapInMapField.put("k2", map2); + + TestWatcher testWatcher = new TestWatcher(GAME); + testWatcher.setMapInMapField(mapInMapField); + + // When + TestWatcher copy = testWatcher.copy(); + + // And + testWatcher.getMapInMapField().get("k2").put("k2.2", "v2.2"); + testWatcher.getMapInMapField().put("k3", new HashMap<>()); + + // Then + Map> copyMapInMap = copy.getMapInMapField(); + assertEquals(2, copyMapInMap.size()); + assertTrue(copyMapInMap.containsKey("k1")); + assertEquals(ImmutableMap.of("k1.1", "v1.1", "k1.2", "v1.2"), copyMapInMap.get("k1")); + assertTrue(copyMapInMap.containsKey("k2")); + assertEquals(ImmutableMap.of("k2.1", "v2.1"), copyMapInMap.get("k2")); + assertFalse(copyMapInMap.containsKey("k3")); + } + private Set set(String... values) { return Stream.of(values).collect(Collectors.toSet()); } @@ -51,6 +153,9 @@ public class WatcherTest { private String stringField; private Set setField = new HashSet<>(); private Map mapField = new HashMap<>(); + private Map> listInMapField = new HashMap<>(); + private Map> setInMapField = new HashMap<>(); + private Map> mapInMapField = new HashMap<>(); public TestWatcher(WatcherScope scope) { super(scope); @@ -84,5 +189,29 @@ public class WatcherTest { public void setMapField(Map mapField) { this.mapField = mapField; } + + public Map> getListInMapField() { + return listInMapField; + } + + public void setListInMapField(Map> listInMapField) { + this.listInMapField = listInMapField; + } + + public Map> getSetInMapField() { + return setInMapField; + } + + public void setSetInMapField(Map> setInMapField) { + this.setInMapField = setInMapField; + } + + public Map> getMapInMapField() { + return mapInMapField; + } + + public void setMapInMapField(Map> mapInMapField) { + this.mapInMapField = mapInMapField; + } } } From d9d7dd49bacc3a1709951dc8477791ebb921dac8 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Mon, 15 Jun 2020 23:36:17 +0400 Subject: [PATCH 2/2] Merge fix --- .../plugins/card/dl/sources/ScryfallImageSupportTokens.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportTokens.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportTokens.java index 908dd265ffc..4fc76ae7aab 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportTokens.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportTokens.java @@ -110,7 +110,6 @@ public class ScryfallImageSupportTokens { put("AKH/Anointer Priest", "https://api.scryfall.com/cards/takh/2/en?format=image"); put("AKH/Aven Initiate", "https://api.scryfall.com/cards/takh/3/en?format=image"); put("AKH/Aven Wind Guide", "https://api.scryfall.com/cards/takh/4/en?format=image"); - put("AKH/Gideon of the Trials Emblem", "https://api.scryfall.com/cards/takh/25/en?format=image"); put("AKH/Glyph Keeper", "https://api.scryfall.com/cards/takh/5/en?format=image"); put("AKH/Heart-Piercer Manticore", "https://api.scryfall.com/cards/takh/6/en?format=image"); put("AKH/Honored Hydra", "https://api.scryfall.com/cards/takh/7/en?format=image"); @@ -204,9 +203,6 @@ public class ScryfallImageSupportTokens { put("BFZ/Octopus", "https://api.scryfall.com/cards/tbfz/7/en?format=image"); put("BFZ/Plant", "https://api.scryfall.com/cards/tbfz/10/en?format=image"); - // C17 - - // WAR put("WAR/Angel", "https://api.scryfall.com/cards/twar/2/en?format=image"); put("WAR/Assassin", "https://api.scryfall.com/cards/twar/6/en?format=image");