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