1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.configuration.beanutils;
18
19 import java.beans.PropertyDescriptor;
20 import java.lang.reflect.InvocationTargetException;
21 import java.util.Collection;
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Set;
27
28 import org.apache.commons.beanutils.BeanUtils;
29 import org.apache.commons.beanutils.PropertyUtils;
30 import org.apache.commons.configuration.ConfigurationRuntimeException;
31 import org.apache.commons.lang.ClassUtils;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 public final class BeanHelper
61 {
62
63 private static final Map<String, BeanFactory> BEAN_FACTORIES = Collections
64 .synchronizedMap(new HashMap<String, BeanFactory>());
65
66
67
68
69
70 private static BeanFactory defaultBeanFactory = DefaultBeanFactory.INSTANCE;
71
72
73
74
75 private BeanHelper()
76 {
77 }
78
79
80
81
82
83
84
85
86
87
88 public static void registerBeanFactory(String name, BeanFactory factory)
89 {
90 if (name == null)
91 {
92 throw new IllegalArgumentException(
93 "Name for bean factory must not be null!");
94 }
95 if (factory == null)
96 {
97 throw new IllegalArgumentException("Bean factory must not be null!");
98 }
99
100 BEAN_FACTORIES.put(name, factory);
101 }
102
103
104
105
106
107
108
109
110
111 public static BeanFactory deregisterBeanFactory(String name)
112 {
113 return BEAN_FACTORIES.remove(name);
114 }
115
116
117
118
119
120
121 public static Set<String> registeredFactoryNames()
122 {
123 return BEAN_FACTORIES.keySet();
124 }
125
126
127
128
129
130
131 public static BeanFactory getDefaultBeanFactory()
132 {
133 return defaultBeanFactory;
134 }
135
136
137
138
139
140
141
142
143 public static void setDefaultBeanFactory(BeanFactory factory)
144 {
145 if (factory == null)
146 {
147 throw new IllegalArgumentException(
148 "Default bean factory must not be null!");
149 }
150 defaultBeanFactory = factory;
151 }
152
153
154
155
156
157
158
159
160
161
162
163 public static void initBean(Object bean, BeanDeclaration data)
164 throws ConfigurationRuntimeException
165 {
166 initBeanProperties(bean, data);
167
168 Map<String, Object> nestedBeans = data.getNestedBeanDeclarations();
169 if (nestedBeans != null)
170 {
171 if (bean instanceof Collection)
172 {
173
174
175 @SuppressWarnings("unchecked")
176 Collection<Object> coll = (Collection<Object>) bean;
177 if (nestedBeans.size() == 1)
178 {
179 Map.Entry<String, Object> e = nestedBeans.entrySet().iterator().next();
180 String propName = e.getKey();
181 Class<?> defaultClass = getDefaultClass(bean, propName);
182 if (e.getValue() instanceof List)
183 {
184
185
186 @SuppressWarnings("unchecked")
187 List<BeanDeclaration> decls = (List<BeanDeclaration>) e.getValue();
188 for (BeanDeclaration decl : decls)
189 {
190 coll.add(createBean(decl, defaultClass));
191 }
192 }
193 else
194 {
195 BeanDeclaration decl = (BeanDeclaration) e.getValue();
196 coll.add(createBean(decl, defaultClass));
197 }
198 }
199 }
200 else
201 {
202 for (Map.Entry<String, Object> e : nestedBeans.entrySet())
203 {
204 String propName = e.getKey();
205 Class<?> defaultClass = getDefaultClass(bean, propName);
206 initProperty(bean, propName, createBean(
207 (BeanDeclaration) e.getValue(), defaultClass));
208 }
209 }
210 }
211 }
212
213
214
215
216
217
218
219
220 public static void initBeanProperties(Object bean, BeanDeclaration data)
221 throws ConfigurationRuntimeException
222 {
223 Map<String, Object> properties = data.getBeanProperties();
224 if (properties != null)
225 {
226 for (Map.Entry<String, Object> e : properties.entrySet())
227 {
228 String propName = e.getKey();
229 initProperty(bean, propName, e.getValue());
230 }
231 }
232 }
233
234
235
236
237
238
239
240 private static Class<?> getDefaultClass(Object bean, String propName)
241 {
242 try
243 {
244 PropertyDescriptor desc = PropertyUtils.getPropertyDescriptor(bean, propName);
245 if (desc == null)
246 {
247 return null;
248 }
249 return desc.getPropertyType();
250 }
251 catch (Exception ex)
252 {
253 return null;
254 }
255 }
256
257
258
259
260
261
262
263
264
265
266 private static void initProperty(Object bean, String propName, Object value)
267 throws ConfigurationRuntimeException
268 {
269 if (!PropertyUtils.isWriteable(bean, propName))
270 {
271 throw new ConfigurationRuntimeException("Property " + propName
272 + " cannot be set on " + bean.getClass().getName());
273 }
274
275 try
276 {
277 BeanUtils.setProperty(bean, propName, value);
278 }
279 catch (IllegalAccessException iaex)
280 {
281 throw new ConfigurationRuntimeException(iaex);
282 }
283 catch (InvocationTargetException itex)
284 {
285 throw new ConfigurationRuntimeException(itex);
286 }
287 }
288
289
290
291
292
293
294
295
296
297
298 public static void setProperty(Object bean, String propName, Object value)
299 {
300 if (PropertyUtils.isWriteable(bean, propName))
301 {
302 initProperty(bean, propName, value);
303 }
304 }
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324 public static Object createBean(BeanDeclaration data, Class<?> defaultClass,
325 Object param) throws ConfigurationRuntimeException
326 {
327 if (data == null)
328 {
329 throw new IllegalArgumentException(
330 "Bean declaration must not be null!");
331 }
332
333 BeanFactory factory = fetchBeanFactory(data);
334 try
335 {
336 return factory.createBean(fetchBeanClass(data, defaultClass,
337 factory), data, param);
338 }
339 catch (Exception ex)
340 {
341 throw new ConfigurationRuntimeException(ex);
342 }
343 }
344
345
346
347
348
349
350
351
352
353
354
355 public static Object createBean(BeanDeclaration data, Class<?> defaultClass)
356 throws ConfigurationRuntimeException
357 {
358 return createBean(data, defaultClass, null);
359 }
360
361
362
363
364
365
366
367
368
369 public static Object createBean(BeanDeclaration data)
370 throws ConfigurationRuntimeException
371 {
372 return createBean(data, null);
373 }
374
375
376
377
378
379
380
381
382
383
384
385
386 static Class<?> loadClass(String name, Class<?> callingClass)
387 throws ClassNotFoundException
388 {
389 return ClassUtils.getClass(name);
390 }
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405 private static Class<?> fetchBeanClass(BeanDeclaration data,
406 Class<?> defaultClass, BeanFactory factory)
407 throws ConfigurationRuntimeException
408 {
409 String clsName = data.getBeanClassName();
410 if (clsName != null)
411 {
412 try
413 {
414 return loadClass(clsName, factory.getClass());
415 }
416 catch (ClassNotFoundException cex)
417 {
418 throw new ConfigurationRuntimeException(cex);
419 }
420 }
421
422 if (defaultClass != null)
423 {
424 return defaultClass;
425 }
426
427 Class<?> clazz = factory.getDefaultBeanClass();
428 if (clazz == null)
429 {
430 throw new ConfigurationRuntimeException(
431 "Bean class is not specified!");
432 }
433 return clazz;
434 }
435
436
437
438
439
440
441
442
443
444
445 private static BeanFactory fetchBeanFactory(BeanDeclaration data)
446 throws ConfigurationRuntimeException
447 {
448 String factoryName = data.getBeanFactoryName();
449 if (factoryName != null)
450 {
451 BeanFactory factory = BEAN_FACTORIES.get(factoryName);
452 if (factory == null)
453 {
454 throw new ConfigurationRuntimeException(
455 "Unknown bean factory: " + factoryName);
456 }
457 else
458 {
459 return factory;
460 }
461 }
462 else
463 {
464 return getDefaultBeanFactory();
465 }
466 }
467 }