1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.ibatis.reflection.wrapper;
18
19 import static org.junit.jupiter.api.Assertions.*;
20
21 import java.util.Arrays;
22 import java.util.HashMap;
23 import java.util.LinkedHashMap;
24 import java.util.List;
25 import java.util.Map;
26
27 import org.apache.ibatis.reflection.DefaultReflectorFactory;
28 import org.apache.ibatis.reflection.MetaObject;
29 import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
30 import org.apache.ibatis.reflection.factory.ObjectFactory;
31 import org.apache.ibatis.reflection.property.PropertyTokenizer;
32 import org.junit.jupiter.api.Test;
33 import org.junit.jupiter.params.ParameterizedTest;
34 import org.junit.jupiter.params.provider.CsvSource;
35
36 class MapWrapperTest {
37
38 @Test
39 void assertBasicOperations() {
40 Map<String, Object> map = new LinkedHashMap<>();
41 map.put("a", "100");
42 map.put("b", null);
43 map.put("my_name", Integer.valueOf(200));
44 MetaObject metaObj = MetaObject.forObject(map, new DefaultObjectFactory(), new DefaultObjectWrapperFactory(),
45 new DefaultReflectorFactory());
46 assertFalse(metaObj.isCollection());
47 assertTrue(metaObj.hasGetter("a"));
48 assertTrue(metaObj.hasSetter("a"));
49 assertTrue(metaObj.hasGetter("b.anykey"));
50 assertEquals("a", metaObj.findProperty("a", false));
51 assertEquals("b", metaObj.findProperty("b", false));
52 assertEquals("my_name", metaObj.findProperty("my_name", false));
53 assertEquals("my_name", metaObj.findProperty("my_name", true));
54 assertArrayEquals(new String[] { "a", "b", "my_name" }, metaObj.getGetterNames());
55 assertArrayEquals(new String[] { "a", "b", "my_name" }, metaObj.getSetterNames());
56 assertEquals(String.class, metaObj.getGetterType("a"));
57 assertEquals(Object.class, metaObj.getGetterType("b"));
58 assertEquals(Integer.class, metaObj.getGetterType("my_name"));
59 assertEquals(String.class, metaObj.getSetterType("a"));
60 assertEquals(Object.class, metaObj.getSetterType("b"));
61 assertEquals(Integer.class, metaObj.getSetterType("my_name"));
62 assertEquals("100", metaObj.getValue("a"));
63 assertNull(metaObj.getValue("b"));
64 assertEquals(Integer.valueOf(200), metaObj.getValue("my_name"));
65 try {
66 metaObj.add("x");
67 fail();
68 } catch (UnsupportedOperationException e) {
69
70 }
71 try {
72 metaObj.addAll(Arrays.asList("x", "y"));
73 fail();
74 } catch (UnsupportedOperationException e) {
75
76 }
77 metaObj.setValue("a", Long.valueOf(900L));
78 assertEquals(Long.valueOf(900L), map.get("a"));
79 }
80
81 @Test
82 void assertNonExistentKey() {
83 Map<String, Object> map = new HashMap<>();
84 map.put("a", "100");
85 MetaObject metaObj = MetaObject.forObject(map, new DefaultObjectFactory(), new DefaultObjectWrapperFactory(),
86 new DefaultReflectorFactory());
87 assertEquals("anykey", metaObj.findProperty("anykey", false));
88 assertFalse(metaObj.hasGetter("anykey"));
89 assertFalse(metaObj.hasGetter("child.anykey"));
90 assertEquals(Object.class, metaObj.getGetterType("anykey"));
91 assertEquals(Object.class, metaObj.getGetterType("child.anykey"));
92 assertTrue(metaObj.hasSetter("anykey"));
93 assertTrue(metaObj.hasSetter("child.anykey"));
94 assertEquals(Object.class, metaObj.getSetterType("anykey"));
95 assertEquals(Object.class, metaObj.getSetterType("child.anykey"));
96 assertNull(metaObj.getValue("anykey"));
97
98 metaObj.setValue("anykey", Integer.valueOf(200));
99 metaObj.setValue("child.anykey", Integer.valueOf(300));
100 assertEquals(3, map.size());
101 assertEquals(Integer.valueOf(200), map.get("anykey"));
102 @SuppressWarnings("unchecked")
103 Map<String, Object> childMap = (Map<String, Object>) map.get("child");
104 assertEquals(Integer.valueOf(300), childMap.get("anykey"));
105 }
106
107 @Test
108 void assertChildBean() {
109 Map<String, Object> map = new HashMap<>();
110 TestBean bean = new TestBean();
111 bean.setPropA("aaa");
112 map.put("bean", bean);
113 MetaObject metaObj = MetaObject.forObject(map, new DefaultObjectFactory(), new DefaultObjectWrapperFactory(),
114 new DefaultReflectorFactory());
115 assertTrue(metaObj.hasGetter("bean.propA"));
116 assertEquals(String.class, metaObj.getGetterType("bean.propA"));
117 assertEquals(String.class, metaObj.getSetterType("bean.propA"));
118 assertEquals("aaa", metaObj.getValue("bean.propA"));
119
120 assertNull(metaObj.getValue("bean.propB"));
121 metaObj.setValue("bean.propB", "bbb");
122 assertEquals("bbb", bean.getPropB());
123
124 metaObj.setValue("bean.propA", "ccc");
125 assertEquals("ccc", bean.getPropA());
126 }
127
128 static class TestBean {
129 private String propA;
130 private String propB;
131
132 public String getPropA() {
133 return propA;
134 }
135
136 public void setPropA(String propA) {
137 this.propA = propA;
138 }
139
140 public String getPropB() {
141 return propB;
142 }
143
144 public void setPropB(String propB) {
145 this.propB = propB;
146 }
147 }
148
149 @Test
150 void accessIndexedList() {
151 Map<String, Object> map = new HashMap<>();
152 List<String> list = Arrays.asList("a", "b", "c");
153 map.put("list", list);
154 MetaObject metaObj = MetaObject.forObject(map, new DefaultObjectFactory(), new DefaultObjectWrapperFactory(),
155 new DefaultReflectorFactory());
156 assertEquals("b", metaObj.getValue("list[1]"));
157
158 metaObj.setValue("list[2]", "x");
159 assertEquals("x", list.get(2));
160
161 try {
162 metaObj.setValue("list[3]", "y");
163 fail();
164 } catch (IndexOutOfBoundsException e) {
165
166 }
167
168 assertTrue(metaObj.hasGetter("list[1]"));
169 assertTrue(metaObj.hasSetter("list[1]"));
170
171
172 }
173
174 @Test
175 void accessIndexedMap() {
176 Map<String, Object> map = new HashMap<>();
177 Map<String, String> submap = new HashMap<>();
178 submap.put("a", "100");
179 submap.put("b", "200");
180 submap.put("c", "300");
181 map.put("submap", submap);
182 MetaObject metaObj = MetaObject.forObject(map, new DefaultObjectFactory(), new DefaultObjectWrapperFactory(),
183 new DefaultReflectorFactory());
184 assertEquals("200", metaObj.getValue("submap[b]"));
185
186 metaObj.setValue("submap[c]", "999");
187 assertEquals("999", submap.get("c"));
188
189 metaObj.setValue("submap[d]", "400");
190 assertEquals(4, submap.size());
191 assertEquals("400", submap.get("d"));
192
193 assertTrue(metaObj.hasGetter("submap[b]"));
194 assertTrue(metaObj.hasGetter("submap[anykey]"));
195 assertTrue(metaObj.hasSetter("submap[d]"));
196 assertTrue(metaObj.hasSetter("submap[anykey]"));
197 }
198
199 @ParameterizedTest
200 @CsvSource({ "abc[def]", "abc.def", "abc.def.ghi", "abc[d.ef].ghi" })
201 void testCustomMapWrapper(String key) {
202 Map<String, Object> map = new HashMap<>();
203 MetaObject metaObj = MetaObject.forObject(map, new DefaultObjectFactory(), new FlatMapWrapperFactory(),
204 new DefaultReflectorFactory());
205 metaObj.setValue(key, "1");
206 assertEquals("1", map.get(key));
207 assertEquals("1", metaObj.getValue(key));
208 }
209
210 static class FlatMapWrapperFactory implements ObjectWrapperFactory {
211 @Override
212 public boolean hasWrapperFor(Object object) {
213 return object instanceof Map;
214 }
215
216 @SuppressWarnings("unchecked")
217 @Override
218 public ObjectWrapper getWrapperFor(MetaObject metaObject, Object object) {
219 return new FlatMapWrapper(metaObject, (Map<String, Object>) object, metaObject.getObjectFactory());
220 }
221 }
222
223 static class FlatMapWrapper extends MapWrapper {
224 public FlatMapWrapper(MetaObject metaObject, Map<String, Object> map, ObjectFactory objectFactory) {
225 super(metaObject, map);
226 }
227
228 @Override
229 public Object get(PropertyTokenizer prop) {
230 String key;
231 if (prop.getChildren() == null) {
232 key = prop.getIndexedName();
233 } else {
234 key = prop.getIndexedName() + "." + prop.getChildren();
235 }
236 return map.get(key);
237 }
238
239 @Override
240 public void set(PropertyTokenizer prop, Object value) {
241 String key;
242 if (prop.getChildren() == null) {
243 key = prop.getIndexedName();
244 } else {
245 key = prop.getIndexedName() + "." + prop.getChildren();
246 }
247 map.put(key, value);
248 }
249 }
250
251 }