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 java.util.List;
19
20 import org.apache.ibatis.reflection.ExceptionUtil;
21 import org.apache.ibatis.reflection.MetaClass;
22 import org.apache.ibatis.reflection.MetaObject;
23 import org.apache.ibatis.reflection.ReflectionException;
24 import org.apache.ibatis.reflection.SystemMetaObject;
25 import org.apache.ibatis.reflection.factory.ObjectFactory;
26 import org.apache.ibatis.reflection.invoker.Invoker;
27 import org.apache.ibatis.reflection.property.PropertyTokenizer;
28
29
30
31
32 public class BeanWrapper extends BaseWrapper {
33
34 private final Object object;
35 private final MetaClass metaClass;
36
37 public BeanWrapper(MetaObject metaObject, Object object) {
38 super(metaObject);
39 this.object = object;
40 this.metaClass = MetaClass.forClass(object.getClass(), metaObject.getReflectorFactory());
41 }
42
43 @Override
44 public Object get(PropertyTokenizer prop) {
45 if (prop.getIndex() != null) {
46 Object collection = resolveCollection(prop, object);
47 return getCollectionValue(prop, collection);
48 } else {
49 return getBeanProperty(prop, object);
50 }
51 }
52
53 @Override
54 public void set(PropertyTokenizer prop, Object value) {
55 if (prop.getIndex() != null) {
56 Object collection = resolveCollection(prop, object);
57 setCollectionValue(prop, collection, value);
58 } else {
59 setBeanProperty(prop, object, value);
60 }
61 }
62
63 @Override
64 public String findProperty(String name, boolean useCamelCaseMapping) {
65 return metaClass.findProperty(name, useCamelCaseMapping);
66 }
67
68 @Override
69 public String[] getGetterNames() {
70 return metaClass.getGetterNames();
71 }
72
73 @Override
74 public String[] getSetterNames() {
75 return metaClass.getSetterNames();
76 }
77
78 @Override
79 public Class<?> getSetterType(String name) {
80 PropertyTokenizerrty/PropertyTokenizer.html#PropertyTokenizer">PropertyTokenizer prop = new PropertyTokenizer(name);
81 if (prop.hasNext()) {
82 MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
83 if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
84 return metaClass.getSetterType(name);
85 } else {
86 return metaValue.getSetterType(prop.getChildren());
87 }
88 } else {
89 return metaClass.getSetterType(name);
90 }
91 }
92
93 @Override
94 public Class<?> getGetterType(String name) {
95 PropertyTokenizerrty/PropertyTokenizer.html#PropertyTokenizer">PropertyTokenizer prop = new PropertyTokenizer(name);
96 if (prop.hasNext()) {
97 MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
98 if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
99 return metaClass.getGetterType(name);
100 } else {
101 return metaValue.getGetterType(prop.getChildren());
102 }
103 } else {
104 return metaClass.getGetterType(name);
105 }
106 }
107
108 @Override
109 public boolean hasSetter(String name) {
110 PropertyTokenizerrty/PropertyTokenizer.html#PropertyTokenizer">PropertyTokenizer prop = new PropertyTokenizer(name);
111 if (prop.hasNext()) {
112 if (metaClass.hasSetter(prop.getIndexedName())) {
113 MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
114 if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
115 return metaClass.hasSetter(name);
116 } else {
117 return metaValue.hasSetter(prop.getChildren());
118 }
119 } else {
120 return false;
121 }
122 } else {
123 return metaClass.hasSetter(name);
124 }
125 }
126
127 @Override
128 public boolean hasGetter(String name) {
129 PropertyTokenizerrty/PropertyTokenizer.html#PropertyTokenizer">PropertyTokenizer prop = new PropertyTokenizer(name);
130 if (prop.hasNext()) {
131 if (metaClass.hasGetter(prop.getIndexedName())) {
132 MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
133 if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
134 return metaClass.hasGetter(name);
135 } else {
136 return metaValue.hasGetter(prop.getChildren());
137 }
138 } else {
139 return false;
140 }
141 } else {
142 return metaClass.hasGetter(name);
143 }
144 }
145
146 @Override
147 public MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory) {
148 MetaObject metaValue;
149 Class<?> type = getSetterType(prop.getName());
150 try {
151 Object newObject = objectFactory.create(type);
152 metaValue = MetaObject.forObject(newObject, metaObject.getObjectFactory(), metaObject.getObjectWrapperFactory(), metaObject.getReflectorFactory());
153 set(prop, newObject);
154 } catch (Exception e) {
155 throw new ReflectionException("Cannot set value of property '" + name + "' because '" + name + "' is null and cannot be instantiated on instance of " + type.getName() + ". Cause:" + e.toString(), e);
156 }
157 return metaValue;
158 }
159
160 private Object getBeanProperty(PropertyTokenizer prop, Object object) {
161 try {
162 Invoker method = metaClass.getGetInvoker(prop.getName());
163 try {
164 return method.invoke(object, NO_ARGUMENTS);
165 } catch (Throwable t) {
166 throw ExceptionUtil.unwrapThrowable(t);
167 }
168 } catch (RuntimeException e) {
169 throw e;
170 } catch (Throwable t) {
171 throw new ReflectionException("Could not get property '" + prop.getName() + "' from " + object.getClass() + ". Cause: " + t.toString(), t);
172 }
173 }
174
175 private void setBeanProperty(PropertyTokenizer prop, Object object, Object value) {
176 try {
177 Invoker method = metaClass.getSetInvoker(prop.getName());
178 Object[] params = {value};
179 try {
180 method.invoke(object, params);
181 } catch (Throwable t) {
182 throw ExceptionUtil.unwrapThrowable(t);
183 }
184 } catch (Throwable t) {
185 throw new ReflectionException("Could not set property '" + prop.getName() + "' of '" + object.getClass() + "' with value '" + value + "' Cause: " + t.toString(), t);
186 }
187 }
188
189 @Override
190 public boolean isCollection() {
191 return false;
192 }
193
194 @Override
195 public void add(Object element) {
196 throw new UnsupportedOperationException();
197 }
198
199 @Override
200 public <E> void addAll(List<E> list) {
201 throw new UnsupportedOperationException();
202 }
203
204 }