Skip to content

Commit 3b8eab0

Browse files
feat(xml-map): add map of string type serialization/deserialization support (#102)
This commit adds the support for serialization and deserialization of map of string type properties in the core library. This utility class will be used to annotate and handle map of string type properties in SDK models, ensuring proper serialization and deserialization.
1 parent 4898a4b commit 3b8eab0

2 files changed

Lines changed: 217 additions & 0 deletions

File tree

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package io.apimatic.core.utilities;
2+
3+
import java.util.ArrayList;
4+
import java.util.HashMap;
5+
import java.util.List;
6+
import java.util.Map;
7+
import java.util.Map.Entry;
8+
9+
import javax.xml.bind.annotation.XmlAnyElement;
10+
import javax.xml.bind.annotation.adapters.XmlAdapter;
11+
import javax.xml.parsers.DocumentBuilder;
12+
import javax.xml.parsers.DocumentBuilderFactory;
13+
14+
import org.w3c.dom.Document;
15+
import org.w3c.dom.Element;
16+
17+
/**
18+
* This is a utility class for XML map marshalling and unmarshalling.
19+
*/
20+
public class MapAdapter extends XmlAdapter<MapAdapter.EntryList, Map<String, String>> {
21+
22+
/**
23+
* Holds the element entries of the map.
24+
*/
25+
public static class EntryList {
26+
@XmlAnyElement
27+
private List<Element> entries = new ArrayList<Element>();
28+
29+
/**
30+
* Getter for the element entries.
31+
* @return entries The list of elements.
32+
*/
33+
public List<Element> getEntries() {
34+
return entries;
35+
}
36+
}
37+
38+
@Override
39+
public EntryList marshal(Map<String, String> map) throws Exception {
40+
if (map == null) {
41+
return null;
42+
}
43+
44+
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
45+
Document document = docBuilder.newDocument();
46+
EntryList adaptedMap = new EntryList();
47+
for (Entry<String, String> entry : map.entrySet()) {
48+
Element element = document.createElement("entry");
49+
element.setAttribute("key", entry.getKey());
50+
element.setTextContent(entry.getValue());
51+
adaptedMap.entries.add(element);
52+
}
53+
return adaptedMap;
54+
}
55+
56+
@Override
57+
public Map<String, String> unmarshal(EntryList adaptedMap) throws Exception {
58+
if (adaptedMap == null) {
59+
return null;
60+
}
61+
62+
HashMap<String, String> map = new HashMap<String, String>();
63+
for (Element element : adaptedMap.entries) {
64+
map.put(element.getAttribute("key"), element.getTextContent());
65+
}
66+
return map;
67+
}
68+
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
package apimatic.core.utilities;
2+
3+
import org.junit.Test;
4+
import org.w3c.dom.Document;
5+
import org.w3c.dom.Element;
6+
import io.apimatic.core.utilities.MapAdapter;
7+
import javax.xml.parsers.DocumentBuilder;
8+
import javax.xml.parsers.DocumentBuilderFactory;
9+
import static org.junit.Assert.assertEquals;
10+
import static org.junit.Assert.assertNotNull;
11+
import static org.junit.Assert.assertNull;
12+
import static org.junit.Assert.assertTrue;
13+
import java.util.HashMap;
14+
import java.util.Map;
15+
16+
public class MapAdapterTest {
17+
18+
private final MapAdapter mapAdapter = new MapAdapter();
19+
20+
@Test
21+
public void marshalShouldReturnEntryListWhenGivenNonEmptyMap() throws Exception {
22+
// Arrange
23+
Map<String, String> inputMap = new HashMap<>();
24+
inputMap.put("key1", "value1");
25+
inputMap.put("key2", "value2");
26+
27+
// Act
28+
MapAdapter.EntryList result = mapAdapter.marshal(inputMap);
29+
30+
// Assert
31+
assertEquals(2, result.getEntries().size());
32+
assertTrue(result.getEntries().stream()
33+
.anyMatch(e -> e.getAttribute("key").equals("key1")
34+
&& e.getTextContent().equals("value1")));
35+
assertTrue(result.getEntries().stream()
36+
.anyMatch(e -> e.getAttribute("key").equals("key2")
37+
&& e.getTextContent().equals("value2")));
38+
}
39+
40+
@Test
41+
public void marshalShouldReturnEmptyEntryListWhenGivenEmptyMap() throws Exception {
42+
// Arrange
43+
Map<String, String> inputMap = new HashMap<>();
44+
45+
// Act
46+
MapAdapter.EntryList result = mapAdapter.marshal(inputMap);
47+
48+
// Assert
49+
assertNotNull(result);
50+
assertTrue(result.getEntries().isEmpty());
51+
}
52+
53+
@Test
54+
public void unmarshalShouldReturnMapWhenGivenNonEmptyEntryList() throws Exception {
55+
// Arrange
56+
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
57+
Document document = docBuilder.newDocument();
58+
Element entry1 = document.createElement("entry");
59+
entry1.setAttribute("key", "key1");
60+
entry1.setTextContent("value1");
61+
62+
Element entry2 = document.createElement("entry");
63+
entry2.setAttribute("key", "key2");
64+
entry2.setTextContent("value2");
65+
66+
MapAdapter.EntryList entryList = new MapAdapter.EntryList();
67+
entryList.getEntries().add(entry1);
68+
entryList.getEntries().add(entry2);
69+
70+
// Act
71+
Map<String, String> result = mapAdapter.unmarshal(entryList);
72+
73+
// Assert
74+
assertEquals(2, result.size());
75+
assertEquals("value1", result.get("key1"));
76+
assertEquals("value2", result.get("key2"));
77+
}
78+
79+
@Test
80+
public void unmarshalShouldReturnEmptyMapWhenGivenEmptyEntryList() throws Exception {
81+
// Arrange
82+
MapAdapter.EntryList entryList = new MapAdapter.EntryList();
83+
84+
// Act
85+
Map<String, String> result = mapAdapter.unmarshal(entryList);
86+
87+
// Assert
88+
assertNotNull(result);
89+
assertTrue(result.isEmpty());
90+
}
91+
92+
@Test
93+
public void marshalShouldHandleNullValues() throws Exception {
94+
// Arrange
95+
Map<String, String> inputMap = new HashMap<>();
96+
inputMap.put("key1", null);
97+
98+
// Act
99+
MapAdapter.EntryList result = mapAdapter.marshal(inputMap);
100+
101+
// Assert
102+
assertEquals(1, result.getEntries().size());
103+
assertEquals("", result.getEntries().get(0).getTextContent());
104+
}
105+
106+
@Test
107+
public void marshalShouldHandleNullMap() throws Exception {
108+
// Arrange
109+
Map<String, String> inputMap = null;
110+
111+
// Act
112+
MapAdapter.EntryList result = mapAdapter.marshal(inputMap);
113+
114+
// Assert
115+
assertNull(result);
116+
}
117+
118+
@Test
119+
public void unmarshalShouldHandleNullEntry() throws Exception {
120+
// Arrange
121+
MapAdapter.EntryList entryList = null;
122+
123+
// Act
124+
Map<String, String> result = mapAdapter.unmarshal(entryList);
125+
126+
// Assert
127+
assertNull(result);
128+
}
129+
130+
@Test
131+
public void unmarshalShouldHandleEntriesWithEmptyTextContent() throws Exception {
132+
// Arrange
133+
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
134+
Document document = docBuilder.newDocument();
135+
Element entry1 = document.createElement("entry");
136+
entry1.setAttribute("key", "key1");
137+
entry1.setTextContent("");
138+
139+
MapAdapter.EntryList entryList = new MapAdapter.EntryList();
140+
entryList.getEntries().add(entry1);
141+
142+
// Act
143+
Map<String, String> result = mapAdapter.unmarshal(entryList);
144+
145+
// Assert
146+
assertEquals(1, result.size());
147+
assertEquals("", result.get("key1"));
148+
}
149+
}

0 commit comments

Comments
 (0)