View Javadoc
1   /*
2    *    Copyright 2009-2024 the original author or authors.
3    *
4    *    Licensed under the Apache License, Version 2.0 (the "License");
5    *    you may not use this file except in compliance with the License.
6    *    You may obtain a copy of the License at
7    *
8    *       https://www.apache.org/licenses/LICENSE-2.0
9    *
10   *    Unless required by applicable law or agreed to in writing, software
11   *    distributed under the License is distributed on an "AS IS" BASIS,
12   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *    See the License for the specific language governing permissions and
14   *    limitations under the License.
15   */
16  package org.apache.ibatis.reflection.wrapper;
17  
18  import static org.junit.jupiter.api.Assertions.assertArrayEquals;
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertFalse;
21  import static org.junit.jupiter.api.Assertions.assertNull;
22  import static org.junit.jupiter.api.Assertions.assertTrue;
23  import static org.junit.jupiter.api.Assertions.fail;
24  
25  import java.util.ArrayList;
26  import java.util.Arrays;
27  import java.util.List;
28  
29  import org.apache.ibatis.reflection.DefaultReflectorFactory;
30  import org.apache.ibatis.reflection.MetaObject;
31  import org.apache.ibatis.reflection.ReflectionException;
32  import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
33  import org.junit.jupiter.api.Test;
34  
35  class BeanWrapperTest {
36  
37    @Test
38    void assertBasicOperations() {
39      Bean1 bean = new Bean1();
40      MetaObject metaObj = MetaObject.forObject(bean, new DefaultObjectFactory(), new DefaultObjectWrapperFactory(),
41          new DefaultReflectorFactory());
42      assertFalse(metaObj.isCollection());
43      assertTrue(metaObj.hasGetter("id"));
44      assertTrue(metaObj.hasSetter("id"));
45      assertTrue(metaObj.hasGetter("bean2.id"));
46      assertTrue(metaObj.hasSetter("bean2.id"));
47      assertEquals("id", metaObj.findProperty("id", false));
48      assertNull(metaObj.findProperty("attr_val", false));
49      assertEquals("attrVal", metaObj.findProperty("attr_val", true));
50      String[] getterNames = metaObj.getGetterNames();
51      Arrays.sort(getterNames);
52      assertArrayEquals(new String[] { "attrVal", "bean2", "bean2List", "id", "nums" }, getterNames);
53      String[] setterNames = metaObj.getSetterNames();
54      Arrays.sort(setterNames);
55      assertArrayEquals(new String[] { "attrVal", "bean2", "bean2List", "id", "nums" }, setterNames);
56      assertEquals(String.class, metaObj.getGetterType("attrVal"));
57      assertEquals(String.class, metaObj.getSetterType("attrVal"));
58      assertEquals(String.class, metaObj.getGetterType("bean2.name"));
59      assertEquals(String.class, metaObj.getSetterType("bean2.name"));
60  
61      assertTrue(metaObj.hasGetter("bean2List[0]"));
62      try {
63        metaObj.getValue("bean2List[0]");
64        fail();
65      } catch (ReflectionException e) {
66        assertEquals("Cannot get the value 'bean2List[0]' because the property 'bean2List' is null.", e.getMessage());
67      }
68      try {
69        metaObj.setValue("bean2List[0]", new Bean2());
70        fail();
71      } catch (ReflectionException e) {
72        assertEquals("Cannot set the value 'bean2List[0]' because the property 'bean2List' is null.", e.getMessage());
73      }
74      assertTrue(metaObj.hasSetter("bean2List[0]"));
75  
76      List<Bean2> bean2List = new ArrayList<>();
77      for (int i = 0; i < 3; i++) {
78        Bean2 bean2 = new Bean2();
79        bean2.setId(i);
80        bean2.setName("name_" + i);
81        bean2List.add(bean2);
82      }
83      bean.setBean2List(bean2List);
84  
85      assertEquals(0, metaObj.getValue("bean2List[0].id"));
86  
87      metaObj.setValue("attrVal", "value");
88      assertEquals("value", bean.getAttrVal());
89      try {
90        metaObj.getValue("attrVal[0]");
91        fail();
92      } catch (ReflectionException e) {
93        assertEquals("Cannot get the value 'attrVal[0]' because the property 'attrVal' is not Map, List or Array.",
94            e.getMessage());
95      }
96      try {
97        metaObj.setValue("attrVal[0]", "blur");
98        fail();
99      } catch (ReflectionException e) {
100       assertEquals("Cannot set the value 'attrVal[0]' because the property 'attrVal' is not Map, List or Array.",
101           e.getMessage());
102     }
103 
104     metaObj.setValue("bean2List[1].name", "new name 1");
105     assertEquals("new name 1", bean.getBean2List().get(1).getName());
106 
107     try {
108       metaObj.getValue("nums[0]");
109       fail();
110     } catch (ReflectionException e) {
111       // pass
112     }
113     metaObj.setValue("nums", new Integer[] { 5, 6, 7 });
114     assertTrue(metaObj.hasGetter("bean2List[0].child.id"));
115     assertTrue(metaObj.hasSetter("bean2List[0].child.id"));
116 
117     {
118       Bean2 bean2 = new Bean2();
119       bean2.setId(100);
120       bean2.setName("name_100");
121       metaObj.setValue("bean2", bean2);
122       assertEquals(String.class, metaObj.getGetterType("bean2.name"));
123       assertEquals(String.class, metaObj.getSetterType("bean2.name"));
124     }
125 
126     try {
127       metaObj.setValue("bean2.child.bean2", "bogus");
128       fail();
129     } catch (ReflectionException e) {
130       // pass
131     }
132 
133     {
134       Bean2 bean2 = new Bean2();
135       bean2.setId(101);
136       bean2.setName("name_101");
137       metaObj.setValue("bean2.child.bean2", bean2);
138       assertEquals(101, bean.getBean2().getChild().getBean2().getId());
139     }
140 
141     metaObj.setValue("bean2.child.nums", new Integer[] { 8, 9 });
142     metaObj.setValue("bean2.child.nums[0]", 88);
143     assertEquals(88, bean.getBean2().getChild().getNums()[0]);
144 
145     assertFalse(metaObj.hasSetter("x[0].y"));
146     assertFalse(metaObj.hasGetter("x[0].y"));
147 
148     try {
149       metaObj.getValue("x");
150       fail();
151     } catch (ReflectionException e) {
152       // pass
153     }
154     // assertEquals(Integer.class, metaObj.getSetterType("my_name"));
155     // assertEquals("100", metaObj.getValue("a"));
156     // assertNull(metaObj.getValue("b"));
157     // assertEquals(Integer.valueOf(200), metaObj.getValue("my_name"));
158     try {
159       metaObj.add("x");
160       fail();
161     } catch (UnsupportedOperationException e) {
162       // pass
163     }
164     try {
165       metaObj.addAll(Arrays.asList("x", "y"));
166       fail();
167     } catch (UnsupportedOperationException e) {
168       // pass
169     }
170   }
171 
172   static class Bean1 {
173     private Integer id;
174     private String attrVal;
175     private Integer[] nums;
176     private Bean2 bean2;
177     private List<Bean2> bean2List;
178 
179     public Integer getId() {
180       return id;
181     }
182 
183     public void setId(Integer id) {
184       this.id = id;
185     }
186 
187     public String getAttrVal() {
188       return attrVal;
189     }
190 
191     public void setAttrVal(String attrVal) {
192       this.attrVal = attrVal;
193     }
194 
195     public Integer[] getNums() {
196       return nums;
197     }
198 
199     public void setNums(Integer[] nums) {
200       this.nums = nums;
201     }
202 
203     public Bean2 getBean2() {
204       return bean2;
205     }
206 
207     public void setBean2(Bean2 bean2) {
208       this.bean2 = bean2;
209     }
210 
211     public List<Bean2> getBean2List() {
212       return bean2List;
213     }
214 
215     public void setBean2List(List<Bean2> bean2List) {
216       this.bean2List = bean2List;
217     }
218   }
219 
220   static class Bean2 {
221     private Integer id;
222     private String name;
223     private Bean1 child;
224 
225     public Integer getId() {
226       return id;
227     }
228 
229     public void setId(Integer id) {
230       this.id = id;
231     }
232 
233     public String getName() {
234       return name;
235     }
236 
237     public void setName(String name) {
238       this.name = name;
239     }
240 
241     public Bean1 getChild() {
242       return child;
243     }
244 
245     public void setChild(Bean1 child) {
246       this.child = child;
247     }
248   }
249 }