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