|
45 | 45 | import org.springframework.data.rest.webmvc.mapping.Associations;
|
46 | 46 | import org.springframework.util.ObjectUtils;
|
47 | 47 |
|
| 48 | +import com.fasterxml.jackson.annotation.JsonAnyGetter; |
| 49 | +import com.fasterxml.jackson.annotation.JsonAnySetter; |
48 | 50 | import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
49 | 51 | import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
|
50 | 52 | import com.fasterxml.jackson.annotation.JsonIgnore;
|
@@ -110,6 +112,7 @@ void setUp() {
|
110 | 112 | mappingContext.getPersistentEntity(BugModel.class);
|
111 | 113 | mappingContext.getPersistentEntity(ArrayListHolder.class);
|
112 | 114 | mappingContext.getPersistentEntity(MapWrapper.class);
|
| 115 | + mappingContext.getPersistentEntity(SlotsContainer.class); |
113 | 116 | mappingContext.afterPropertiesSet();
|
114 | 117 |
|
115 | 118 | this.entities = new PersistentEntities(Collections.singleton(mappingContext));
|
@@ -804,6 +807,36 @@ void augmentsCollectionForPatch() throws Exception {
|
804 | 807 | assertThat(result.items.get(1).some).isEqualTo("otherValue");
|
805 | 808 | assertThat(result.items.get(2).some).isEqualTo("yetAnotherValue");
|
806 | 809 | }
|
| 810 | + |
| 811 | + @Test // GH-2407 |
| 812 | + void deserializesAnySetterForPatch() throws Exception { |
| 813 | + |
| 814 | + Slots slots = new Slots(); |
| 815 | + slots.slots.add(new Slot("slot-1", 1)); |
| 816 | + slots.slots.add(new Slot("slot-2", null)); |
| 817 | + slots.slots.add(new Slot("slot-3", 3)); |
| 818 | + slots.slots.add(new Slot("slot-4", 4)); |
| 819 | + |
| 820 | + SlotsContainer container = new SlotsContainer(); |
| 821 | + container.slots = slots; |
| 822 | + |
| 823 | + // changing value of slot-1, setting one for slot-2, removing for slot-4, leaving slot-3 unchanged |
| 824 | + JsonNode node = new ObjectMapper() |
| 825 | + .readTree("{ \"slots\" : { \"slot-1\" : 12 , \"slot-2\" : 2, \"slot-4\" : null } }"); |
| 826 | + |
| 827 | + SlotsContainer result = reader.doMerge((ObjectNode) node, container, new ObjectMapper()); |
| 828 | + |
| 829 | + final List<Slot> list = new ArrayList<>(result.slots.slots); |
| 830 | + assertThat(list).hasSize(4); |
| 831 | + assertThat(list.get(0).name).isEqualTo("slot-1"); |
| 832 | + assertThat(list.get(0).value).isEqualTo(12); |
| 833 | + assertThat(list.get(1).name).isEqualTo("slot-2"); |
| 834 | + assertThat(list.get(1).value).isEqualTo(2); |
| 835 | + assertThat(list.get(2).name).isEqualTo("slot-3"); |
| 836 | + assertThat(list.get(2).value).isEqualTo(3); |
| 837 | + assertThat(list.get(3).name).isEqualTo("slot-4"); |
| 838 | + assertThat(list.get(3).value).isNull(); |
| 839 | + } |
807 | 840 |
|
808 | 841 | @SuppressWarnings("unchecked")
|
809 | 842 | private static <T> T as(Object source, Class<T> type) {
|
@@ -1201,4 +1234,51 @@ public void setValues(Collection<String> values) {
|
1201 | 1234 | static class MapWrapper {
|
1202 | 1235 | public Map<String, Object> map = new HashMap<>();
|
1203 | 1236 | }
|
| 1237 | + |
| 1238 | + // GH-2407 |
| 1239 | + |
| 1240 | + @JsonAutoDetect(fieldVisibility = Visibility.ANY) |
| 1241 | + static class SlotsContainer { |
| 1242 | + |
| 1243 | + Slots slots; |
| 1244 | + |
| 1245 | + } |
| 1246 | + |
| 1247 | + static class Slots { |
| 1248 | + |
| 1249 | + // The internal, non-json representation is a Set |
| 1250 | + @JsonIgnore private SortedSet<Slot> slots = new TreeSet<>(); |
| 1251 | + |
| 1252 | + @JsonAnySetter |
| 1253 | + public void put(final String name, final Integer value) { |
| 1254 | + slots.removeIf(slot -> slot.name.equals(name)); |
| 1255 | + slots.add(new Slot(name, value)); |
| 1256 | + } |
| 1257 | + |
| 1258 | + // We expose however a Map |
| 1259 | + @JsonAnyGetter |
| 1260 | + public Map<String, Integer> toMap() { |
| 1261 | + final Map<String, Integer> map = new HashMap<>(); |
| 1262 | + slots.forEach(slot -> map.put(slot.name, slot.value)); |
| 1263 | + return map; |
| 1264 | + } |
| 1265 | + } |
| 1266 | + |
| 1267 | + @JsonAutoDetect(fieldVisibility = Visibility.ANY) |
| 1268 | + static class Slot implements Comparable<Slot> { |
| 1269 | + |
| 1270 | + String name; |
| 1271 | + Integer value; |
| 1272 | + |
| 1273 | + Slot(String name, Integer value) { |
| 1274 | + this.name = name; |
| 1275 | + this.value = value; |
| 1276 | + } |
| 1277 | + |
| 1278 | + @Override |
| 1279 | + public int compareTo(Slot o) { |
| 1280 | + return name.compareTo(o.name); |
| 1281 | + } |
| 1282 | + |
| 1283 | + } |
1204 | 1284 | }
|
0 commit comments