1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package ch.qos.logback.core.joran.util;
16
17 import ch.qos.logback.core.Context;
18 import ch.qos.logback.core.joran.spi.DefaultNestedComponentRegistry;
19 import ch.qos.logback.core.joran.util.beans.BeanDescription;
20 import ch.qos.logback.core.joran.util.beans.BeanDescriptionCache;
21 import ch.qos.logback.core.spi.ContextAwareBase;
22 import ch.qos.logback.core.util.AggregationType;
23 import ch.qos.logback.core.util.PropertySetterException;
24 import ch.qos.logback.core.util.StringUtil;
25
26 import java.lang.reflect.Method;
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 public class PropertySetter extends ContextAwareBase {
52
53 protected final Object obj;
54 protected final Class<?> objClass;
55 protected final BeanDescription beanDescription;
56 protected final AggregationAssessor aggregationAssessor;
57
58
59
60
61
62
63
64 public PropertySetter(BeanDescriptionCache beanDescriptionCache, Object obj) {
65 this.obj = obj;
66 this.objClass = obj.getClass();
67 this.beanDescription = beanDescriptionCache.getBeanDescription(objClass);
68 this.aggregationAssessor = new AggregationAssessor(beanDescriptionCache, this.objClass);
69 }
70
71 @Override
72 public void setContext(Context context) {
73 super.setContext(context);
74 aggregationAssessor.setContext(context);
75 }
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94 public void setProperty(String name, String value) {
95 if (value == null) {
96 return;
97 }
98 Method setter = aggregationAssessor.findSetterMethod(name);
99 if (setter == null) {
100 addWarn("No setter for property [" + name + "] in " + objClass.getName() + ".");
101 } else {
102 try {
103 setProperty(setter, value);
104 } catch (PropertySetterException ex) {
105 addWarn("Failed to set property [" + name + "] to value \"" + value + "\". ", ex);
106 }
107 }
108 }
109
110
111
112
113
114
115
116
117 private void setProperty(Method setter, String value) throws PropertySetterException {
118 Class<?>[] paramTypes = setter.getParameterTypes();
119
120 Object arg;
121
122 try {
123 arg = StringToObjectConverter.convertArg(this, value, paramTypes[0]);
124 } catch (Throwable t) {
125 throw new PropertySetterException("Conversion to type [" + paramTypes[0] + "] failed. ", t);
126 }
127
128 if (arg == null) {
129 throw new PropertySetterException("Conversion to type [" + paramTypes[0] + "] failed.");
130 }
131 try {
132 setter.invoke(obj, arg);
133 } catch (Exception ex) {
134 throw new PropertySetterException(ex);
135 }
136 }
137
138 public AggregationType computeAggregationType(String name) {
139 return this.aggregationAssessor.computeAggregationType(name);
140 }
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178 public Class<?> getObjClass() {
179 return objClass;
180 }
181
182 public void addComplexProperty(String name, Object complexProperty) {
183 Method adderMethod = aggregationAssessor.findAdderMethod(name);
184
185 if (adderMethod != null) {
186 Class<?>[] paramTypes = adderMethod.getParameterTypes();
187 if (!isSanityCheckSuccessful(name, adderMethod, paramTypes, complexProperty)) {
188 return;
189 }
190 invokeMethodWithSingleParameterOnThisObject(adderMethod, complexProperty);
191 } else {
192 addError("Could not find method [" + "add" + name + "] in class [" + objClass.getName() + "].");
193 }
194 }
195
196 void invokeMethodWithSingleParameterOnThisObject(Method method, Object parameter) {
197 Class<?> ccc = parameter.getClass();
198 try {
199 method.invoke(this.obj, parameter);
200 } catch (Exception e) {
201 addError("Could not invoke method " + method.getName() + " in class " + obj.getClass().getName()
202 + " with parameter of type " + ccc.getName(), e);
203 }
204 }
205
206 public void addBasicProperty(String name, String strValue) {
207
208 if (strValue == null) {
209 return;
210 }
211
212 name = StringUtil.capitalizeFirstLetter(name);
213 Method adderMethod =aggregationAssessor.findAdderMethod(name);
214
215 if (adderMethod == null) {
216 addError("No adder for property [" + name + "].");
217 return;
218 }
219
220 Class<?>[] paramTypes = adderMethod.getParameterTypes();
221 isSanityCheckSuccessful(name, adderMethod, paramTypes, strValue);
222
223 Object arg;
224 try {
225 arg = StringToObjectConverter.convertArg(this, strValue, paramTypes[0]);
226 } catch (Throwable t) {
227 addError("Conversion to type [" + paramTypes[0] + "] failed. ", t);
228 return;
229 }
230 if (arg != null) {
231 invokeMethodWithSingleParameterOnThisObject(adderMethod, arg);
232 }
233 }
234
235 public void setComplexProperty(String name, Object complexProperty) {
236 Method setter = aggregationAssessor.findSetterMethod(name);
237
238 if (setter == null) {
239 addWarn("Not setter method for property [" + name + "] in " + obj.getClass().getName());
240
241 return;
242 }
243
244 Class<?>[] paramTypes = setter.getParameterTypes();
245
246 if (!isSanityCheckSuccessful(name, setter, paramTypes, complexProperty)) {
247 return;
248 }
249 try {
250 invokeMethodWithSingleParameterOnThisObject(setter, complexProperty);
251
252 } catch (Exception e) {
253 addError("Could not set component " + obj + " for parent component " + obj, e);
254 }
255 }
256
257 private boolean isSanityCheckSuccessful(String name, Method method, Class<?>[] params, Object complexProperty) {
258 Class<?> ccc = complexProperty.getClass();
259 if (params.length != 1) {
260 addError("Wrong number of parameters in setter method for property [" + name + "] in "
261 + obj.getClass().getName());
262
263 return false;
264 }
265
266 if (!params[0].isAssignableFrom(complexProperty.getClass())) {
267 addError("A \"" + ccc.getName() + "\" object is not assignable to a \"" + params[0].getName()
268 + "\" variable.");
269 addError("The class \"" + params[0].getName() + "\" was loaded by ");
270 addError("[" + params[0].getClassLoader() + "] whereas object of type ");
271 addError("\"" + ccc.getName() + "\" was loaded by [" + ccc.getClassLoader() + "].");
272 return false;
273 }
274
275 return true;
276 }
277
278 public Object getObj() {
279 return obj;
280 }
281
282
283 public Class<?> getClassNameViaImplicitRules(String name, AggregationType aggregationType,
284 DefaultNestedComponentRegistry registry) {
285 return aggregationAssessor.getClassNameViaImplicitRules(name, aggregationType, registry);
286 }
287
288 }